Replaces the TTL-based event queue (internal/events) with a proper
in-memory pub-sub bus (internal/eventbus) backed by simonfxr/pubsub.
The agent/events 9P endpoint is now a streaming subscriber: clients
block on reads and receive one JSON-encoded event per read until they
disconnect. Each open(2) creates a per-connection subscription; clunk
and connection teardown cancel it automatically.
- internal/eventbus/bus.go: new package wrapping simonfxr/pubsub;
provides Publish(agent, type, data) and Subscribe() -> (chan, cancel)
- internal/events/events.go: deleted
- internal/session/manager.go: SetEventQueue -> SetEventBus; all
publish sites updated to use eventbus constants
- internal/p9/server.go: fid gains eventCh/eventUnsub fields; Topen
subscribes, Tread blocks on channel, Tclunk/serve-defer cancel
- cmd/anvilsrv/main.go: wired to SetEventBus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the inbox processing loop that auto-completed PROMPT_RESPONSE
messages, so they now stay in the user's inbox like all other types.
Update message.go grouping and SKILL.md docs accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend changes:
- Add CreatedAt() to Session interface
- Implement CreatedAt() in tmux.Session (field already existed)
- Sort Manager.List() by creation time descending
Benefits:
- Deterministic ordering (no more random map iteration)
- Newest sessions appear first (most useful)
- All clients benefit immediately
- head -1 now reliably gets most recent session
README:
- Update example to use head -1 for newest session
- Document that list is sorted newest first
- Emit initial state change event (stopped -> starting) when session is created
- Rename 'exited' state to 'killed' for clarity
- Remove duplicate killed event emission (Close() already emits via transitionToLocked)
- Set OnStateChange callback in NewManager to emit state change events
- All state changes now properly emit events via callbacks
- Wire all state changes in tmux session to use transitionToLocked (triggers OnStateChange)
- Close() exited state
- Refresh() stopped states (intentional stop, restart spam prevention, auto-restart failure, PID=0)
- Add event callbacks to mailbox manager for send/receive events
- Callbacks fire when message removed from outbox (send) and delivered to inbox (receive)
- Consistent with state change callback pattern
- Fix /events 9p read handler to respect offset/count
- Prevents infinite read loop by properly signaling EOF
- Uses readFile() pattern like /list for consistency
- Updated anvillm-communication skill to use MCP tools
- Changed session.go to instruct agents to use send_message
- Updated manager.go to tell agents to use read_inbox
- Updated Claude hook to mention read_inbox tool
- Cleaner, more consistent interface across all documentation
- Fix PROMPT_RESPONSE messages not auto-completing
- Remove deprecated message types (LogInfo, LogError, StatusUpdate)
- Remove entire chat log system (replaced by audit log)
- Migrate user prompts to mailbox system in main.go
- Remove {id}/in and {id}/out 9P endpoints
- Only mail processor uses sess.Send() directly
- Fix file index constants after removing in/out files
- Remove unused SendCtl function
- Created internal/audit package for centralized logging
- Replaced per-session log files with single agent/audit file
- Updated all UIs (TUI, web, Emacs) to use centralized audit log
- Modified mailbox manager to log all message deliveries with aliases
- Updated Alog script to stream centralized audit log
- Removed session-specific log streaming in favor of global audit log
- Remove reserved flag and all reservation logic (unnecessary for kiro-cli)
- Fix session ID file creation: detect kiro-cli runs directly in pane
- Add retry loop for FindBackendPID with kiro-cli detection
- Update hooks to use PPID's parent (kiro-cli PID) instead of 15569
- Remove 5-second delay from running->idle transition
- Clean up workflow scripts: remove explicit skill references and communication protocol sections
- Update researcher roles to use knowledge base, web, and codebase
- Drain all outbox messages in batch instead of one per tick
- Process inbound messages synchronously to ensure delivery before completion
- Keep failed messages in inbox for retry instead of re-delivering
- Simplify control flow with early continue pattern
Message to user now triggers idle state automatically.
Removed separate idle signal instruction from prompts.
Single action (send to user) replaces two-step process.
- Add agent/user/ directory with inbox/outbox/completed
- User is first-class participant (not a session)
- Bot->user: bot writes to outbox with to="user"
- User->bot: user writes to user/outbox with to="{session-id}"
- User inbox messages written to sender's log file
- Add mailbox manager with inbox/outbox/completed structure
- Expose mailboxes via 9P filesystem (agent/{id}/inbox, outbox, completed)
- Mail processor runs every 5s to deliver messages from outbox to inbox
- Messages delivered when recipient is idle, formatted and sent via in file
- Retry logic: 3 attempts max, then discard with notification to sender
- Race condition fixes: messages moved to completed before sending
- Auto-generate message ID and timestamp if missing from bot's JSON
- Update peer-bot skill to use mailbox system with JSON format
- Update all workflows (DevReview, DevReviewQA, Planning) with:
- Explicit shell command examples for sending messages
- plan9 task for all agents
- Mailbox instructions without markdown code blocks
- Fix idle signaling: bots must write summary to out BEFORE signaling idle
- All messages archived in completed/ with proper metadata
- Add global.yaml base config (renamed from sandbox.yaml)
- Add backend-specific configs (claude.yaml, kiro-cli.yaml)
- Add role configs (developer, reviewer, tester, architect, etc.)
- Add task configs (git, docker, go, rust, python, nodejs, etc.)
- Implement config merging: global + backend + role + tasks
- Update workflows to use roles and tasks
- Create tester role with read-only source, execute-only bins
- Fix reviewer role to use rox for bin directories
- Auto-create RW directories that don't exist
- Make backend configs required (fail if missing)
- Update mkfile to install cfg files to ~/.config/anvillm
- Remove Role-Based Sessions from IDEAS.md (now implemented)