When slinging to an existing polecat with --naked flag, the code was still
attempting to look up the tmux pane, which fails for terminated polecats.
Now resolveTargetAgent accepts a skipPane parameter that bypasses the tmux
pane and working directory lookup when true.
This allows work to be slung to terminated polecats that will be restarted
manually later.
Also updated unsling to skip pane lookup since it only needs the agent ID.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The main polecat spawn fix was already in place (ec29ca07), but the naked
mode help text was telling users to run `claude` without the flag. Updated
to show the correct command with --dangerously-skip-permissions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the primary wake mechanism for patrol agents:
- Subscribes to bd activity --follow as a background process
- Returns immediately when any line of output is received
- Timeout with optional exponential backoff as safety net
- JSON output mode for scripting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Before: gt crew at only looked for tmux sessions with the specific naming
convention gt-<rig>-crew-<name>. If the user started Claude manually or
via a different mechanism, it would create a duplicate session.
After: Before creating a new session, check if any existing tmux session
has Claude running in the crews directory. If found, attach to that
session instead of creating a new one.
Changes:
- Add FindSessionByWorkDir() to internal/tmux/tmux.go to search sessions
by working directory, optionally filtering for Claude (node) running
- Update runCrewAt() to check for existing sessions before creating new
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a new 'gt commit' command that wraps git commit and automatically
injects agent identity trailers into commit messages:
- Executed-By: agent identity (e.g., beads/crew/dave)
- Rig: the rig name
- Role: crew, polecat, witness, etc.
- Molecule: pinned molecule ID if any
This enables forensic analysis and audit trails for agent-mediated commits.
Supports common git commit flags: -a, --amend, --no-edit, --allow-empty.
Use --no-trailers to skip adding identity trailers.
- Add special handling for 'deacon' target in gt nudge command
- Maps 'deacon' to gt-deacon session, gracefully handles if not running
- Add gt nudge deacon session-started to SessionStart hooks
- Updated settings-autonomous.json, settings-interactive.json, and
ensurePatrolHooks() template
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds first-class support for the human overseer in Gas Town mail:
- New OverseerConfig in internal/config/overseer.go with identity
detection (git config, gh cli, environment)
- Overseer detected/saved on town install (mayor/overseer.json)
- Simplified detectSender(): GT_ROLE set = agent, else = overseer
- New overseer address alongside mayor/ and deacon/
- Added --cc flag to mail send for CC recipients
- Inbox now includes CC'd messages via label query
- gt status shows overseer identity and unread mail count
- New gt whoami command shows current mail identity
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The swarm Manager was maintaining an in-memory map of swarms that was
never persisted and duplicated state from beads. This caused stale state
after restarts and confusion about source of truth.
Changes:
- Remove swarms map from Manager (now stateless)
- Add LoadSwarm() that queries beads for swarm state
- Refactor all methods to use LoadSwarm() instead of in-memory lookup
- Discover workers from assigned tasks in beads
- Remove obsolete unit tests that tested in-memory behavior
- Keep type/state tests that do not need beads
The E2E test (gt-kc7yj.4) now covers the beads integration.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed icon from 📌 to 🪝 for hooked beads
- Changed label from "Pinned" to "Hooked"
- Added 🚀 AUTONOMOUS MODE banner when work is on hook
- Clarified that hooked bead triggers autonomous work even without molecule
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add "The Capability Ledger" section to all 6 role templates explaining:
- Work visibility and reputation
- Redemption through consistent quality
- Every completion as evidence of autonomous execution at scale
- Work history as growing portfolio/CV
Also fix hooked vs pinned terminology confusion:
- "Hooked" = work assigned to you (triggers autonomous mode)
- "Pinned" = permanent reference beads
- Add clarifying note to all startup behavior sections
- Update code examples to use --status=hooked
Update prime.go AUTONOMOUS MODE output with ledger framing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt crew remove runs, it now closes the associated agent bead
(gt-<rig>-crew-<name>) with reason "Crew workspace removed".
This prevents orphaned agent beads in the system after crew removal.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- checkSlungWork now queries for status=hooked instead of status=pinned
- This makes AUTONOMOUS WORK MODE fire correctly when work is slung via gt hook
- Added "physics not politeness" language to AUTONOMOUS MODE output
- Added full Theory of Operation section to refinery.md.tmpl for consistency
The bug was: gt hook sets status=hooked but gt prime was querying for
status=pinned, so AUTONOMOUS MODE never triggered for hooked work.
(gt-kc7yj.3)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The hook mechanism was broken because gt hook sets status=hooked
but gt mol status was querying for status=pinned.
Adds StatusHooked constant and updates queries accordingly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements canonical naming convention for agent bead IDs:
- Town-level: gt-mayor, gt-deacon (unchanged)
- Rig-level: gt-<rig>-witness, gt-<rig>-refinery (was gt-witness-<rig>)
- Named: gt-<rig>-crew-<name>, gt-<rig>-polecat-<name> (was gt-crew-<rig>-<name>)
Changes:
- Added AgentBeadID helper functions to internal/beads/beads.go
- Updated all ID generation call sites to use helpers
- Fixed session parsing in theme.go, statusline.go, agents.go
- Updated doctor check and fix to use canonical format
- Updated tests for new format
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When run from inside a crew directory like gastown/crew/joe, the command
now auto-detects the crew workspace name instead of requiring it as an
argument. This matches the existing behavior of 'gt crew at'.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All agent bead creation now uses shared role beads:
- gt-mayor-role, gt-deacon-role
- gt-witness-role, gt-refinery-role
- gt-crew-role, gt-polecat-role
Previous code created per-instance role bead references like
gt-witness-gastown-role which is wrong. Role beads are shared
class definitions, not per-instance.
Files fixed:
- internal/rig/manager.go
- internal/doctor/agent_beads_check.go
- internal/cmd/prime.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
crew_add.go: Use gt-crew-role instead of per-instance role bead
polecat/manager.go: Add RoleBead field pointing to gt-polecat-role
Per agent-as-bead design, role beads are shared class definitions.
Each agent bead references its role via the role_bead field/slot.
Fixes gt-ne9he
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace .runtime/swarms.json with beads-backed swarm tracking:
- gt swarm create: calls bd create --type=epic --mol-type=swarm
- gt swarm status: calls bd swarm status
- gt swarm list: calls bd list --mol-type=swarm --type=epic
- gt swarm start: uses bd swarm status to find ready tasks
- gt swarm land: checks completion via bd, closes epic
- gt swarm cancel: closes epic with cancelled reason
Removed:
- SwarmStore type and LoadSwarmStore/Save functions
- Old spawnSwarmWorkers (replaced with spawnSwarmWorkersFromBeads)
- Unused helper functions (stateStyle, taskStateIcon, matchesStatus)
This implements "discovery over tracking" principle from swarm-architecture.md:
swarm state is now derived from beads epic/issue statuses rather than
maintaining separate state in .runtime/swarms.json.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show unread mail count and first message subject for each agent
- Display format: "mail: 📬 N unread → Subject..."
- Only shows mail line when agent has unread messages
- Fix agent bead ID generation for global agents (mayor/, deacon/)
Example output:
🏭 Refinery
gt-refinery-gastown running
hook: refinery Handoff
mail: 📬 8 unread → MERGE_READY morsov
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show full agent bead ID for each agent (e.g., gt-crew-gastown-joe)
- Display hook/pinned work with bead ID and title
- Use role icons and section separators for clarity
- Fall back to hooks array when agent bead lacks hook_bead field
Example output:
🎩 Mayor
gt-mayor running
hook: (none)
─── gastown/ ───────────────────────
🏭 Refinery
gt-refinery-gastown running
hook: refinery Handoff
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use tree characters (├── └── │) for hierarchical display
- Group agents by role type (Witness, Refinery, Crew, Polecats)
- Add role icons (🎩 Mayor, 🔔 Deacon, 👁 Witness, 🏭 Refinery, 👷 Crew, 😺 Polecats)
- Show pinned work inline with truncation
- Fix unused import in polecat/manager.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Inverse of 'gt rig shutdown'. Starts rig patrol agents:
- Checks tmux sessions to avoid duplicates
- Starts witness if not running
- Starts refinery if not running
- Reports what was started vs skipped
Also adds ProcessExists util function needed by witness/refinery managers.
- polecat.go: Remove unreachable first loop in splitLines (was using filepath.SplitList incorrectly)
- townlog/logger.go: Remove unused Event.JSON() method and json import
- lock/lock.go: Remove unused ErrStaleLock error variable
- refinery/manager.go: Remove unused getTestCommand() method
Note: witness.StatePaused is actually used by cmd/witness.go, not dead code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added constants.SupportedShells for consistent shell list
- Updated 7 usages across start.go, crew_lifecycle.go, crew_helpers.go, tmux.go
- All tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PrintWarning helper in internal/style/style.go
- Update 35 warning message outputs across 16 files to use consistent format
- All warnings now display as "⚠ Warning: <message>" in yellow/bold
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of Go code checking git state to decide if polecat removal is safe,
the polecat now self-reports its cleanup_status via its agent bead.
Changes:
- Add CleanupStatus field to AgentFields struct
- Update FormatAgentDescription and ParseAgentFields for cleanup_status
- Add UpdateAgentCleanupStatus function to beads package
- Update gt done to compute and report git cleanup status
- Update RemoveWithOptions to read cleanup_status from agent bead first,
falling back to git check for backward compatibility
Valid cleanup_status values:
- clean: no uncommitted work
- has_uncommitted: has uncommitted changes
- has_stash: has stashed changes
- has_unpushed: has unpushed commits
- unknown: git check failed
This follows ZFC (Zero Figuring in Code) principles - the polecat is the
authority on its own state, not Go code inferring it from external signals.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extended the unified cycle system to include rig infrastructure sessions:
- Witness ↔ Refinery (per rig) now cycle with C-b n/p
Also moved SetCycleBindings into ConfigureGasTownSession so ALL Gas Town
sessions automatically get the unified cycle bindings. Removed redundant
individual calls from crew, mayor, and deacon startup code.
Cycle groups are now:
- Town: Mayor ↔ Deacon
- Crew (per rig): All crew members in same rig
- Infra (per rig): Witness ↔ Refinery
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fail fast with clear error when run outside ~/gt instead of
hanging while bd tries to start.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reduced runStart from 126 lines to 48 lines by extracting:
- startCoreAgents: Mayor and Deacon session startup (28 lines)
- startRigAgents: Witness/Refinery startup for --all flag (37 lines)
- startConfiguredCrew: Auto-start configured crew members (29 lines)
No behavior change - all existing tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add bubbletea and bubbles dependencies
- Create internal/tui/feed package with:
- model.go: Main bubbletea model with agent tree and event stream
- view.go: Rendering logic with lipgloss styling
- keys.go: Vim-style key bindings (j/k, tab, /, q)
- styles.go: Color palette and component styles
- events.go: Event source from bd activity
- Update gt feed to use TUI by default (--plain for text mode)
- TUI features: agent tree by role, event stream, keyboard nav
Closes gt-be0as, gt-lexye, gt-1uhmj
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create AgentIdentity type to parse and construct session names, replacing
duplicated logic in sling.go and handoff.go.
- Add internal/session/identity.go with AgentIdentity type
- ParseSessionName handles: mayor, deacon, witness, refinery, crew, polecat
- SessionName() reconstructs valid tmux session name
- Address() returns mail-style address (e.g., "gastown/crew/max")
- GTRole() returns GT_ROLE env var format
- Update sling.go:sessionToAgentID to use ParseSessionName
- Update handoff.go:sessionToGTRole to use ParseSessionName
- Add comprehensive unit tests with round-trip verification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sessionToAgentID function was missing handling for polecat sessions,
causing gt sling to fail to update the agent bead's hook_bead field.
Before: gt-gastown-nux -> gt-gastown-nux (unchanged, no match)
After: gt-gastown-nux -> gastown/polecats/nux (correct format)
This enables updateAgentHookBead to properly convert to the agent bead ID
(gt-polecat-gastown-nux) and update the hook_bead field, which is
required for agents to know they have work on their hook.
Found via E2E test (gt-j0gx2) - nux wasn't picking up slung work because
hook_bead was null despite the task being pinned.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Claude needs ~2 seconds to initialize before it can process nudges.
Without this delay, the initial "Work slung" message would arrive
before Claude was ready, causing the SessionStart hook not to fire.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous implementation set separate bindings for crew vs town
sessions, but tmux key bindings are global. This meant whichever
session type was started last would overwrite the other's bindings.
New approach:
- Add unified `gt cycle next/prev` command that auto-detects session type
- Town sessions (gt-mayor, gt-deacon) cycle within town group
- Crew sessions (gt-*-crew-*) cycle within their rig's crew
- Other sessions (polecats, witness, refinery) do nothing on cycle
The old SetCrewCycleBindings and SetTownCycleBindings are now aliases
for the unified SetCycleBindings function.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create gt town next/prev commands for cycling between town-level sessions
- Add SetTownCycleBindings() to tmux package
- Wire up bindings when starting mayor and deacon sessions
Now mayor and deacon have the same C-b n/p cycling behavior as crew workers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the nuclear cleanup option for post-merge polecat removal:
- Kills Claude session (force mode)
- Deletes git worktree (bypassing all safety checks)
- Deletes polecat branch
- Closes agent bead
Supports --all for bulk nuke and --dry-run for preview.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the nuclear cleanup option for post-merge polecat removal:
- Kills Claude session (force mode)
- Deletes git worktree (bypassing all safety checks)
- Deletes polecat branch
- Closes agent bead
Supports --all for bulk nuke and --dry-run for preview.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements session-preserving polecat recycle:
- Kills Claude session (tmux kill-session)
- Preserves sandbox (worktree and branch intact)
- Updates agent bead state to 'stopped'
- Leaves polecat ready for respawn on next molecule step
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously gt done wrote MRs to .beads/mq/*.json files, but gt mq list
queried beads for issue_type=merge-request. These were two different
storage systems, so MRs created by gt done never showed in gt mq list.
Now gt done creates a proper MR bead with:
- issue_type: merge-request
- Description containing branch, target, source_issue, rig, worker
Also updated mq_submit.go for consistency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- doctor/agent_beads_check.go: Check and create agent beads for all crew workers
- New listCrewWorkers() helper finds crew directories in each rig
- Run() checks for missing crew agent beads
- Fix() creates missing crew agent beads with proper fields
- cmd/crew_add.go: Create agent bead when adding a crew worker
- Creates gt-crew-<rig>-<name> agent bead after workspace creation
- Non-fatal if bead creation fails (warns but continues)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>