Documents that session events stay in events.jsonl (orchestration),
with work attribution via session_id on beads mutations.
Filed:
- gt-nvz8b: gt done captures session_id
- bd-tksk: Beads session_id support (slung to dave)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a stable actor-PID identifier alongside the Claude session_id.
Useful for correlation across session handoffs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused SessionBeacon function from session/names.go
- Add gt seance commands to reference.md Sessions section
- Document StartupNudge format for session discovery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The SessionStart hook now parses stdin JSON to extract session_id
and passes it to gt prime via CLAUDE_SESSION_ID env var.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements automatic nuke of polecats after completion:
- HandlePolecatDone: Auto-nukes immediately for ESCALATED/DEFERRED exits
(no pending MR) when cleanup_status=clean
- HandleMerged: Auto-nukes after verifying commit is on main and
cleanup_status=clean
- HandleLifecycleShutdown: Auto-nukes immediately since shutdown means
no pending work
Safety checks preserved:
- Verifies cleanup_status from agent bead (clean/has_uncommitted/etc)
- Verifies commit is on main before nuking
- Falls back to cleanup wisp if any check fails
New functions:
- NukePolecat(): Executes gt polecat nuke
- AutoNukeIfClean(): Checks safety and nukes if safe
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Key optimizations:
- Use --no-daemon for bd commands to avoid daemon IPC overhead
- Pre-fetch all agent beads in single query (ListAgentBeads)
- Pre-fetch all hook beads in single query (ShowMultiple)
- Pre-fetch all tmux sessions for O(1) lookup
- Parallel rig processing with goroutines
- Add --fast flag to skip mail lookups
The main bottleneck was bd daemon communication timing out on
stale daemon processes, causing 5+ second delays per rig.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated mol-witness-patrol to properly clean up polecats that exit via
ESCALATED/DEFERRED (no MR). Previously, these polecats would sit idle
indefinitely waiting for a MERGED signal that would never come.
Changes:
- process-cleanups: Check for MR before sending MERGE_READY. If no MR
exists and polecat is clean, nuke immediately.
- survey-workers: Step 3a now handles both idle AND done polecats
without pending MR. Step 4a checks for MR before creating cleanup wisp.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt handoff is run with -s and -m flags, it now:
- Creates the handoff mail bead directly using bd create
- Captures the created bead ID
- Auto-hooks the bead with status=hooked so the next session picks it up
This enables the handoff workflow:
gt handoff -s "Title" -m "Instructions..."
The next session startup hook (gt prime) will detect the hooked bead
and present it to the agent for immediate execution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a mail bead (type=message) is on hook, gt hook now shows:
- From: <sender>
- Subject: <title>
- Run: gt mail read <id>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add "Hookable Mail" section to all role templates explaining how mail beads
can be hooked for ad-hoc instruction handoff. Key documentation points:
- GUPP applies to hooked mail: read and execute instructions
- Two use cases: hook existing mail, create+hook via gt handoff
- Role-specific examples for each agent type
Templates updated:
- boot.md.tmpl
- crew.md.tmpl
- deacon.md.tmpl
- mayor.md.tmpl
- polecat.md.tmpl
- refinery.md.tmpl
- witness.md.tmpl
Also updated prime.go fallback output functions to include hookable mail
reference for when templates fail to render.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The gt hook command was using --status=pinned while gt sling and the rest
of the codebase use --status=hooked. This inconsistency meant gt hook would
not find beads hooked by gt sling, and vice versa.
Changes:
- hook.go: Use beads.StatusHooked instead of beads.StatusPinned
- hook.go: Update bd update command to use --status=hooked
- unsling.go: Use beads.StatusHooked when finding hooked beads
- Update error messages and comments to say "hooked" instead of "pinned"
This fix ensures gt hook works uniformly for all bead types (molecules,
issues, mail beads) since they all use the same beads system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging work from town beads (hq-*) to a polecat whose agent bead
is in rig beads (gt-*), the hook_bead update was silently failing because
bd couldn't find the cross-beads reference.
Changes:
- sling.go: Use town root for routing instead of cwd, enabling cross-beads
resolution via routes.jsonl. Log warnings on failure instead of silent ignore.
- done.go: Use townRoot (already available) instead of cwd for beads client.
Log warnings on failure for both state and cleanup status updates.
Root cause: The beads client was created from current working directory,
which may not have access to routes.jsonl for cross-prefix resolution.
Town root always has routes.jsonl for proper prefix → rig directory mapping.
(gt-ohqxq)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add heartbeat checking to Boot degraded triage: detects stale Deacon
heartbeat (>15min nudges, >30min restarts)
- Add checkDeaconHeartbeat to daemon heartbeat cycle as fallback
- This ensures the Deacon is monitored continuously, not just at startup
The mol-deacon-patrol formula was also updated separately to use
gt deacon health-check instead of ephemeral context memory tracking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The refinery was checking git branches instead of the beads merge queue.
This caused MRs to pile up when branches were deleted but MR beads remained.
- manager.go: Queue() now queries beads for type=merge-request issues
- refinery.md.tmpl: Updated queue-scan to use gt mq list
- mol-refinery-patrol.formula.toml: Updated queue-scan step instructions
- Add docs/hanoi-demo.md with full execution instructions
- Add scripts/gen_hanoi.py for generating larger formulas
- Include pre-generated 7-disk formula (127 moves)
- 9 and 10 disk formulas already committed
Speed test results: 127 issues close in 14 sec (~109ms each)
Expected 1K run time: ~2 minutes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- towers-of-hanoi-9: 511 moves (2^9 - 1)
- towers-of-hanoi-10: 1023 moves (2^10 - 1)
These are fully pre-computed move sequences for durability testing.
The 10-disk version creates 1026 beads issues when poured.
For million-step (20 disks), would need 163MB formula file.
Starting with 1K steps to prove the machinery works.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add title field to all steps (required by cook)
- Use hardcoded 3-disk solution (9 steps) as working proof
- Remove pseudo-syntax generate block (not implemented)
- Version bump to 2
Tested: bd cook --dry-run passes, mol pour creates valid molecule,
execution loop works (all 9 steps can be closed in sequence).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive execution protocol to formula description:
- EXECUTION LOOP: find ready step, close it, repeat
- ON RESUME: same as fresh start, molecule IS the state
- DO/DO NOT guidelines for autonomous execution
- MONITORING guidance for mega-molecules
This enables agents to execute Hanoi autonomously through restarts,
proving nondeterministic idempotence at scale.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major redesign based on design review:
1. REMOVED: Claude Code internal parsing (ZFC violation)
- Deleted internal/claude/sessions.go (parsed ~/.claude/projects/)
- This coupled us to Claude Code's undocumented internal format
2. ADDED: Event-based session discovery
- gt prime now emits session_start events to ~/gt/.events.jsonl
- Events include role, session_id, topic, cwd
- Discovery reads our own event stream (ZFC-compliant)
3. ADDED: --talk flag for actual seances
- gt seance --talk <session-id> spawns: claude --fork-session --resume <id>
- --fork-session creates a new session (read-only, no grave disturbance)
- You literally talk to your predecessor: "Where did you put X?"
4. ADDED: One-shot prompt mode
- gt seance --talk <id> -p "Where is the config?"
- Uses claude --print for quick questions
The name "seance" is now literal - you commune with the dead (past sessions).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Step 3a to survey-workers that automatically nukes idle polecats
with clean git state. Only escalates to Mayor when uncommitted or
unpushed work is detected.
This reduces mail noise - idle polecats without work are pure overhead
and can be safely cleaned up without human intervention.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed table entry from 'Skip (no action needed)' to 'Auto-nuke if clean (Step 3a)'.
TODO: Add Step 3a section with full auto-nuke logic:
- Check git status for uncommitted changes
- Check for unpushed commits
- If clean: gt polecat nuke <name>
- If dirty: escalate to Mayor for recovery decision
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The runSlingFormula function was calling bd wisp which does not exist.
The correct command is bd mol wisp for creating ephemeral molecules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Parses Claude Code ~/.claude/projects/ to find Gas Town sessions.
Sessions are identified by the [GAS TOWN] beacon in startup messages.
Features:
- Filter by role (crew, polecat, witness, etc.)
- Filter by rig name
- Show recent N sessions
- JSON output for scripting
- Sorts by most recent first
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
getTrackedIssues was spawning a separate bd show subprocess for each
tracked issue. With 10 convoys x 5 issues = 50+ subprocesses per poll.
Solution: Use bd show batch capability (bd show id1 id2 id3 --json)
to fetch all issue details in a single call. Falls back to individual
lookups if the batch fails (e.g., invalid IDs).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds context timeouts to bd and sqlite3 calls in the convoy panel TUI.
If these commands hang, the TUI will no longer freeze - it will timeout
after 5 seconds and return empty/error state.
Functions updated:
- listConvoys: bd list with context timeout
- getTrackedIssueStatus: sqlite3 query with context timeout
- getIssueStatus: bd show with context timeout
(gt-14xej)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of hardcoding the rig list (gastown, beads), now loads rigs
from mayor/rigs.json using config.LoadRigsConfig. Falls back gracefully
to just checking global agents if the config cannot be loaded.
(gt-mmp0q)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a third panel to the feed TUI showing:
- In-progress convoys with progress bars (completed/total)
- Recently landed convoys (last 24h) with time since landing
Features:
- Panel cycles with tab: tree -> convoy -> feed
- Direct access via 1/2/3 number keys
- Auto-refresh every 10 seconds
- Styled progress indicators (●●○○)
The convoy panel bridges the gap between "WHO is working" (agent tree)
and "WHAT is happening" (event feed) by showing "WHAT IS SHIPPING".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add RuntimeConfig type to RigSettings allowing per-rig LLM runtime
configuration. This moves hardcoded "claude --dangerously-skip-permissions"
invocations to configurable settings.
Changes:
- Add RuntimeConfig type with Command, Args, InitialPrompt fields
- Add BuildCommand() and BuildCommandWithPrompt() methods
- Add helper functions: LoadRuntimeConfig, BuildAgentStartupCommand,
BuildPolecatStartupCommand, BuildCrewStartupCommand
- Update startup paths in up.go and mayor.go to use new config
- Add comprehensive tests for RuntimeConfig functionality
Remaining hardcoded invocations can be updated incrementally.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The getCleanupStatus function in witness/handlers.go and crew removal
in cmd/crew_lifecycle.go were constructing agent bead IDs with hardcoded
"gt-" prefix. This failed for rigs that use a different prefix like "bd-".
Now uses beads.GetPrefixForRig to look up the correct prefix from
routes.jsonl, enabling support for the beads rig and any future rigs
with custom prefixes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The command now refuses to nuke a polecat unless it passes safety checks:
1. Worktree has no unpushed/uncommitted changes
2. Polecat has no open merge request beads
3. Polecat has no work on its hook
Use --force to bypass these checks (loses work).
Use --dry-run to see safety check status before nuking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Creates internal/session/startup.go with StartupNudgeConfig struct
and StartupNudge function. Format becomes session title in /resume picker:
[GAS TOWN] recipient <- sender • timestamp • topic[:mol-id]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SendKeys has an Enter-concatenation bug that causes the nudge to fail.
NudgeSession is the canonical way to message Claude and works reliably.
Fixes cold starts of crew workers (gt crew start).
(gt-7swyi)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add NudgeChannels field to MessagingConfig struct in types.go
- Initialize NudgeChannels map in NewMessagingConfig()
- Add validation in validateMessagingConfig(): channel names must be
non-empty and each channel must have at least one recipient
- Add tests for valid nudge channels and empty recipient validation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds explicit priming commands at the start of workspace assessment:
- gt prime: Load gt/mol context
- bd prime: Load beads context
Critical for fresh sessions, post-compaction, or context clear scenarios.
Also updates exit criteria to reflect priming requirement.
(gt-0xhuz)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements queue message delivery in internal/mail/router.go:
- Validates queue exists via expandQueue()
- Creates single message (no fan-out unlike lists)
- Stores in town-level beads with queue metadata label
- Uses queue:name as assignee for inbox filtering
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds actual git merge functionality to ProcessMR and ProcessMRFromQueue:
- Fetch source branch from origin
- Checkout target branch and pull latest
- Check for merge conflicts using test merge
- Run configured tests with retry support
- Perform --no-ff merge with descriptive message
- Push to origin
- Return detailed ProcessResult with success/conflict/test status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When adding a dog, creates an agent bead with role_type:dog label.
When removing a dog, deletes the corresponding agent bead.
This enables @dogs group resolution in the mail router by allowing
queries like `bd list --type=agent --label=role_type:dog`.
Changes:
- Add DogBeadID(), DogRoleBeadID() helper functions
- Add CreateDogAgentBead() for creating dog agent beads with labels
- Add FindDogAgentBead() and DeleteDogAgentBead() for cleanup
- Add Labels field to Issue struct for label parsing
- Update ParseAgentBeadID() to handle dog bead IDs (gt-dog-<name>)
- Update IsAgentSessionBead() to include "dog" as valid role
(gt-qha0g)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
After confirming remote branch exists via ls-remote, fetch to ensure
the local origin/branch ref exists before using it in rev-list comparison.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When Mayor creates a convoy, automatically default --notify to 'mayor/'
since the Mayor dispatched the work and should be notified when it lands.
This reduces flag boilerplate for the common case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The `bd slot` command is for agent beads only. Convoy beads aren't agents,
so the slot set failed with exit status 1. The notify address is already
stored in the convoy's description, which is the intended persistence
mechanism.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>