Add doctor check to detect handoff beads for agents that no longer exist.
This happens when a polecat worktree is deleted but its handoff bead remains.
- Check: orphaned-attachments
- Warning if: Handoff bead exists for agent that no longer has worktree
- Supports polecats (rig/name), crew (rig/crew/name), mayor, witness, refinery
- Suggests re-sling to active agent or close the molecule
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add HookInfo struct and hook discovery to show which agents have work
attached to their hooks. Updates both JSON and text output:
- New HookInfo type with agent, role, has_work, molecule, and title fields
- RigStatus now includes Hooks slice
- StatusSum includes ActiveHooks count
- discoverRigHooks() scans polecats, crew, witness, and refinery
- getAgentHook() retrieves hook status from handoff beads
- Text output shows active hooks per rig with agent and molecule info
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows agents to self-pin work from mail messages. The command:
1. Reads a mail message by ID
2. Extracts molecule ID from the body (attached_molecule:, molecule_id:, etc.)
3. Attaches the molecule to the agent's pinned bead (hook)
4. Marks the mail as read
Includes unit tests for the molecule ID extraction logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated all role prompt templates to document the startup hook protocol:
- polecat.md.tmpl: Added gt mol status check, self-pin from mail protocol
- witness.md.tmpl: Added gt mol status check, self-pin from mail protocol
- refinery.md.tmpl: Added gt mol status check, self-pin from mail protocol
- crew.md.tmpl: Added new Startup Protocol section with hook-first flow
- deacon.md.tmpl: Added gt mol status check, self-pin from mail protocol
- mayor.md.tmpl: Expanded startup protocol with hook-first flow
Each template now includes:
1. Check hook first (gt mol status)
2. If empty, check mail for attached work
3. Self-pin protocol (gt mol attach-from-mail) if needed
4. Role-specific fallback behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a command to list all hooks in the workspace. Scans for .claude/settings.json
files and displays hooks by type (SessionStart, PreCompact, UserPromptSubmit, etc).
Features:
- Scans town root, rigs, polecats, crew, witness, and refinery directories
- Shows hook type, location, status, and agent that owns it
- Supports --verbose flag to show hook commands
- Supports --json flag for machine-readable output
(gt-h6eq.5)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add doctor check to ensure each agent has at most one handoff bead.
Detects when multiple pinned beads exist with the same "{role} Handoff"
title, which can cause confusion about which handoff is authoritative.
- Check: hook-singleton
- Error if: Multiple pinned beads with same '{role} Handoff' title
- Fix: Automatically closes duplicates (keeps oldest) when run with --fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a new doctor check that detects attached molecules that
haven't been updated in too long, which may indicate stuck work.
The check:
- Finds all pinned beads with attachments across rigs
- Checks the attached molecule's UpdatedAt timestamp
- Reports molecules in_progress with no activity for >1 hour
- Provides actionable fix hints for stuck polecats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add doctor check to verify that attached molecules exist and are not closed.
Detects when a hook's attached_molecule field points to a non-existent or
closed issue, which can leave agents with stale work assignments.
- Check: hook-attachment-valid
- Error if: Hook's attached_molecule field points to non-existent or closed issue
- Fix: Automatically detaches invalid molecules when run with --fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds Pin() and Unpin() methods to the beads wrapper that call bd pin/unpin.
Updates pinToHook() to call b.Pin() after AttachMolecule() to set the
pinned boolean field and assignee on the work issue. This should enable
bd hook to show pinned work.
NOTE: There's a known issue where bd pin via subprocess doesn't actually
set the pinned field even though it reports success. The handoff bead
attachment remains the primary mechanism until this is resolved.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DefaultCrewName constant ('max') to config package
- Add default_crew_name field to MayorConfig for town-level override
- Update gt rig add to resolve crew name: --crew flag > town config > default
- Update help text to reflect new default
Priority: --crew flag > MayorConfig.DefaultCrewName > config.DefaultCrewName ('max')
Adds support for slinging work to four new target types:
- crew (e.g., beads/crew/dave): Human-managed persistent workers
- No worktree recreation
- No auto-session start
- Sends work assignment mail
- witness (e.g., gastown/witness): Per-rig lifecycle manager
- Suggests --wisp for ephemeral work
- Pins to witness hook
- refinery (e.g., gastown/refinery): Per-rig merge queue
- Accepts protos, issues, and epics
- Pins to refinery hook
- mayor (e.g., mayor/): Town-level coordinator
- Uses town-level beads
- Human-managed like crew
- Sends work assignment mail
Updated help text with new target formats and examples.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The help text documented this subcommand but it wasn't implemented.
Adds status command showing currently resolved account with source
(GT_ACCOUNT env var or default).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds support for managing multiple Claude Code accounts in Gas Town:
- accounts.json config parsing in mayor/ directory
- gt account list/add/default commands
- GT_ACCOUNT env var support with priority resolution
- --account flag on gt spawn and gt crew at commands
- CLAUDE_CONFIG_DIR injection into tmux sessions
Priority order: GT_ACCOUNT env var > --account flag > default from config
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shell loops bypassed the proper lifecycle architecture. Now:
- Witness: Launches Claude directly, daemon/deacon health-scan handles restart
- Deacon: Launches Claude directly, daemon detects exit and restarts
- Daemon: ensureDeaconRunning() now checks if Claude is running (pane cmd)
and restarts it if session exists but Claude has exited
- gt deacon restart: Now does stop+start instead of Ctrl-C
This enforces proper lifecycle flow through LIFECYCLE mail and daemon
heartbeat rather than bypassing it with shell loops.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agents naturally expect `gt handoff -s "Subject" -m "Message"` to work
like `gt mail send`. Now it does:
- Added --subject/-s and --message/-m flags to gt handoff
- Added --self flag to gt mail send for sending to self
- Handoff auto-sends mail to self before respawning pane
This makes agent-initiated handoff more ergonomic - they can include
context in a single command instead of two separate steps.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add auto-spawn logic to outputDeaconPatrolContext()
- Deacon now auto-spawns mol-deacon-patrol if no active patrol
- All three patrol roles now have consistent auto-bond behavior:
Deacon, Witness, Refinery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add outputWitnessPatrolContext() function in prime.go
- Witness now auto-spawns mol-witness-patrol if no active patrol
- Fixed catalog ID parsing (strip trailing colon) for both witness and refinery
- Created mol-witness-patrol template with 10 steps (gt-qflq)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous implementation used session.Manager which only works for polecats.
Refinery and Witness have their own managers that handle their tmux sessions.
- Use refinery.Manager for refinery auto-start
- Use witness.Manager for witness auto-start
- Check state before starting to avoid duplicate starts
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add handling for POLECAT_DONE messages in processShutdownRequests()
- Track which polecats have signaled done (using SpawnedIssues with "done:" prefix)
- For LIFECYCLE:shutdown requests, wait for POLECAT_DONE before cleanup
- Add checkPendingCompletions() to nudge polecats with closed issues
- Add 10-minute timeout with force-kill after waiting for POLECAT_DONE
- Protects against losing MR submissions when Witness cleans up too early
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements redundant systems to ensure infrastructure stays operational:
- gt spawn: Auto-starts refinery and witness if not running
- mol-witness-patrol: Added check-refinery step to verify refinery is alive
This ensures polecats don't wait forever for merges.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New checks:
- crew-state: Validates crew worker state.json files for completeness
Can regenerate missing/invalid state files with --fix
- lifecycle-hygiene: Detects stale lifecycle state that can wedge the deacon
- Stale lifecycle messages in deacon inbox
- Stuck requesting_* flags in state.json when session is healthy
Can clean up with --fix (external intervention when deacon is stuck)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Three related fixes:
1. lifecycle.go: Use gt mail delete instead of gt mail read to prevent
lifecycle requests from accumulating.
2. handoff.go: Return exec claude command for respawn-pane instead of
gt crew at which tries to attach to existing session.
3. handoff.md skill: Work without --cycle and -m flags, send mail separately.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
InstantiateMolecule now supports two formats:
1. New format: If molecule has child issues, copy them as templates
2. Old format: If no children, parse markdown steps from Description
This unifies execution while preserving authoring flexibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add persistent state storage for Witness across wisp burns:
- Add WorkerState and WitnessHandoffState types
- Implement loadHandoffState/saveHandoffState for bead persistence
- Update getNudgeCount/recordNudge to use persistent state
- Add activity tracking integration into healthCheck
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add outputRefineryPatrolContext to gt prime that automatically spawns
the refinery patrol molecule when no active patrol is found. This ensures
the merge queue is always monitored when Refinery starts up.
Key changes:
- Add RoleRefinery to outputMoleculeContext
- Implement outputRefineryPatrolContext with auto-spawn logic
- Check for existing in-progress or open patrol molecules
- Spawn mol-refinery-patrol wisp if none found
(gt-j6s8)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When state.json contains empty JSON {}, the ClonePath and other fields
were left empty, causing "can't find pane/session" errors in gt crew at.
Now backfills essential fields (Name, Rig, ClonePath) if missing.
🤝 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a new command to query what an agent should be working on:
- Finds handoff bead by agent identity
- Parses attached molecule and tracks progress through steps
- Identifies current/next step (in_progress or first ready)
- Reports status: working, naked, complete, or blocked
Usage:
gt molecule current [identity]
gt mol current gastown/furiosa
gt mol current --json
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rename outputCrewAttachmentStatus to outputAttachmentStatus and extend
to support both RoleCrew and RolePolecat. The Propulsion Principle
("If you find something on your hook, YOU RUN IT.") now applies to
all worker types, not just crew.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply the Universal Gas Town Propulsion Principle to all agent templates:
"If you find something on your hook, YOU RUN IT."
Changes:
- deacon.md.tmpl: Hook-first startup, no decision logic
- polecat.md.tmpl: Simplified propulsion startup, molecule-following
- witness.md.tmpl: Wisp slinging when spawning, propulsion loop
- refinery.md.tmpl: Accept slung branches, hook-based execution
Key principle: Agents don't decide whether to do work. They check their hook
and execute what's there. The hook IS the decision.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add git-state subcommand to gt polecat for Witness pre-kill verification.
Checks working tree, unpushed commits, and stashes to determine if a
polecat worktree is clean (safe to kill) or dirty (needs cleanup).
Usage: gt polecat git-state <rig>/<polecat> [--json]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Uses tmux respawn-pane to kill and restart agent sessions in place,
bypassing the handoff/manager flow for quick context cycling.
Supports local recycle (current session) and remote recycle (other
roles) with automatic client switching.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added --exit flag for exit type (COMPLETED, ESCALATED, DEFERRED).
When polecat runs gt done, it now sends mail to Witness with:
- Exit type (COMPLETED, ESCALATED, or DEFERRED)
- Issue ID (if available)
- MR ID (for COMPLETED)
- Branch name
For ESCALATED and DEFERRED, skips MR submission but still notifies
Witness. This enables Witness patrol to see completion in inbox-check
step, verify git state, and close polecat lease.
Paired with spawn notification (gt-r6td) to bracket polecat lifecycle.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt spawn creates a polecat, it now sends POLECAT_STARTED notifications
to both Witness and Deacon:
- Witness receives: "POLECAT_STARTED <polecat>" with issue and session info
- Deacon receives: "POLECAT_STARTED <rig>/<polecat>" with issue and session info
This enables:
- Witness to bond a lease to its patrol wisp
- Deacon to verify worker started (redundancy)
- Both to nudge if worker is idle at prompt
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>