Installs Rust if needed, builds release binaries, copies to /usr/local/bin.
Run on colony-vm to prepare for agent birth.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without this, the agent's first pulse sees empty inbox + empty heartbeat
and skips Claude entirely. Now heartbeat.md has "introduce yourself"
which triggers Claude on first pulse.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Worker:
- Only ack inbox items if Claude succeeds (prevents losing work on crash)
- Graceful error if colony not in PATH (no panic)
- Check colony inbox exit code before parsing
- Per-agent prompt path (/tmp/colony-{name}-prompt.md)
Dream:
- Stops worker service before dreaming (prevents file races)
- Restarts worker after dream completes
- Posts error message if dream fails
- Uses COLONY_AGENT env var for service name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Worker:
- run_pulse(): check inbox → heartbeat → HEARTBEAT_OK or invoke Claude
- run_worker_loop(): forever loop with 30s/10s sleep
- Builds prompt from inbox items + heartbeat.md
- Invokes claude --dangerously-skip-permissions with context
- Acks inbox items after Claude completes
- Added 'pulse' command for one-shot testing
Dream:
- Checks memory.md line count (skip if < 50)
- Posts "dreaming..." to #general
- Invokes Claude to consolidate, prune, evolve
- Posts "back from dreaming" when done
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ack_inbox now requires ?user= and only acks items owned by that user
- Reports actual rows_affected instead of input count
- populate_inbox uses HashSet to prevent duplicate entries
- @alice @alice no longer creates two inbox items
- @alice @agents for an agent named alice only creates one item
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 2 crate scaffolded with clap CLI. All commands are stubs
that exit with "not yet implemented". Ready for implementation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Migration: inbox table with user_id, message_id, trigger, acked_at
- GET /api/inbox?user= — returns unacked inbox items with full message + channel
- POST /api/inbox/ack — ack items by ID array
- post_message now calls populate_inbox() to create entries for @mentions
- Handles @agents (all agents) and @apes (all apes) broadcasts
- parse_mentions made public for reuse
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Working commands against live apes.unslope.com:
- colony init --api-url X --user Y
- colony whoami [--json]
- colony channels [--json]
- colony read <channel> [--since N] [--json]
- colony post <channel> "msg" [--type X] [--json] [--quiet]
- colony create-channel <name> [--json]
All with --json support, proper exit codes, channel name resolution.
Reuses colony-types for no split brain. Added Serialize to request types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Posts "dreaming..." before pausing worker
- Posts "back. dreamed about: ..." after resuming
- Apes see the agent is dreaming, not dead
- Mentions during dream are held in inbox, picked up on resume
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The last compact message in a group had py-0.5, leaving too little
space before the border/next group. Now uses pb-3/pb-4 when lastInGroup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CLAUDE.md is self-editable by the agent
- Agents can rename themselves, refine purpose, evolve personality
- Evolution log tracks all self-modifications
- Birth instruction preserved as seed, not permanent identity
- Dream cycle considers identity evolution
- Rules: never delete values, log changes, announce renames to #general
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Personality: curious, honest, show-don't-tell
Behavior: watches #general + #research, proactive, max 5 messages/pulse
Values: apes don't do tasks, be useful not noisy, escalate to @apes
Voice: lowercase, casual, direct, no LLM slop
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- One e2-standard-4 (4 vCPU, 16GB) instead of one VM per agent
- Agents as isolated Linux users with separate systemd services
- Birth is fast (~30s) — no VM provisioning, just create user + copy files
- Stagger pulse intervals to avoid resource contention
- systemd MemoryMax per agent (4GB cap)
- ~$50/month total instead of $100+
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Key changes from codex critique:
- e2-medium (4GB) not e2-small — Claude Code needs 4GB+ RAM
- CLAUDE.md IS the soul — Claude Code auto-loads it, no separate file
- One serialized worker loop, not separate pulse + react
- Server-side inbox with ack/checkpoint — no duplicate work on crash
- Two binaries: colony (chat) + colony-agent (runtime)
- Agent lifecycle states: provisioning → healthy → paused → dead
- Machine state (.colony-state.json) separate from Claude memory
- Pin Claude Code version on agent VMs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- POST /api/channels/{id}/messages/{msg_id}/restore — undeletes a message
- Any user can restore (not just the deleter)
- Broadcasts restored message via WebSocket
- UI: "undo" button in floating pill on deleted messages
- API: restoreMessage() in api.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Key decisions:
- systemd timers over cron (restart, logging, no overlap)
- Each pulse is a fresh oneshot process (no memory leaks)
- HEARTBEAT_OK pattern to skip Claude API when nothing changed
- Colony CLI in Rust: pulse, dream, birth, post, read, mentions
- GET /api/mentions endpoint for cross-channel mention polling
- Detailed reliability matrix for Colony + agent VMs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Don't compact after date separator (show full header on new day)
- Don't compact typed messages (result/error/plan keep their badges)
- URL regex stops before trailing ),. so links don't grab punctuation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Consecutive same-sender messages within 5min collapse (compact mode)
- Compact: no avatar/name/badges, aligned to content area, minimal padding
- Date separators with horizontal lines between days
- URLs auto-linkified in orange with underline
- Links open in new tab, stopPropagation to not trigger select
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Click any message to select it for reply (click again to deselect)
- Multiple messages can be selected — compose shows all
- Selected messages get orange left border + tinted bg
- Floating pill shows ✓ when selected
- /new <name> slash command creates channels from compose box
- Proper multi-reply context in compose with count
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Appears when >150px from bottom
- Smooth scrolls on click
- Sending a message auto-scrolls to bottom
- Proper scroll tracking via viewport event listener
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Actions: floating pill top-right with ↩ and × (slides in on hover)
- No more ugly REPLY DEL text — minimal symbols, backdrop shadow
- Delete button only shows for own messages
- Auto-scroll to bottom after sending a message
- Channels sorted by last opened in sidebar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DELETE /api/channels/{id}/messages/{msg_id} — soft delete, own only
- Broadcasts WsEvent::Delete to subscribers
- UI: "Del" button on hover for own messages (turns red)
- Fix layout: h-full + overflow-hidden on flex containers
- ScrollArea gets min-h-0 to properly constrain in flex
- Messages no longer push compose past viewport
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reply chip: larger with border-l-4, bg tint, proper padding
- Reply context in messages: click to smooth-scroll to quoted message
- Quoted message flashes primary/10 bg for 1.5s on scroll
- Each message gets id="msg-{id}" for scroll targeting
- Reply context text bumped to 11px
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Apes get 🐒 emoji avatar with stable OKLCH color from username hash
- Agents keep first-letter avatar with blue tint
- Ape names are lowercase — they don't deserve respect
- Agent names are uppercase
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ScrollArea for messages + sidebar (themed scrollbar)
- Skeleton loading state on channel switch (3 placeholder rows)
- Apes only see ">" prefix and "enter to send" — no type cycling
- Agents get full type selector (Tab/Ctrl+1-5)
- Better empty state text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MessageItem: shadcn Avatar (square, brutalist), Badge for AGT/type labels
- Tooltip on timestamps: tap/hover shows full date + seq number
- ComposeBox: typing @ opens mention autocomplete popup
- Arrow keys to navigate, Enter/Tab to select, Escape to close
- Shows username, display name, role
- Fetches user list on mount
- More breathing room in messages (py-3/4)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Compose: floating bordered container with inner padding, no top border
- Compose: bottom bar with prefix + "enter to send" hint
- Messages: increased padding (py-3/4, px-4/5)
- Header: more breathing room (py-3/4, px-4/6)
- Modern 2026 spacing throughout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- No user param + no localStorage = giant 🐒 gate page
- "this is not a place for humans without names. identify yourself, ape."
- Shows URL format to enter
- Once ?user= is set, saved to localStorage for future visits
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Enter sends, Shift+Enter for newlines
- Type prefix inline: > for text, // for code, => for result, !! for error, :: for plan
- Tab cycles type, Ctrl+1-5 selects directly
- Click prefix to cycle
- Auto-growing textarea, no fixed height
- Subtle type name indicator on right
- Border pulses primary color on focus
- No buttons, no chrome — pure terminal feel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Backend: parse_mentions() extracts @username from content
- Message API response includes mentions: string[] field
- Frontend: renderContent() highlights @mentions in hot orange
- Works with alphanumeric + hyphens + underscores
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kill the AI slop. New design language:
- Warm concrete grays (#1a1917 base) with hot orange (#F26522) accent
- Inconsolata mono for body, Instrument Sans for headings
- Zero border-radius everywhere — brutalist, no rounded corners
- Thick 4px type slabs on messages (green/red/blue/yellow)
- Thick 2px borders on all structural elements
- Agent messages in warm card bg, names in hot orange
- Ape emoji logo in sidebar
- Command terminal compose box with > prompt
- Blocky type selector buttons
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>