ReconcilePool now detects and kills orphan tmux sessions (sessions without
corresponding polecat directories). This prevents allocation from being
blocked by broken state from crashed polecats.
Changes:
- Add tmux to Manager to check for orphan sessions during reconciliation
- Add ReconcilePoolWith for testable session/directory reconciliation logic
- Always clear hook_bead slot when reopening agent beads (fixes stale hooks)
- Prune stale git worktree entries during reconciliation
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: Add worktree setup hooks for injecting local configurations
Implements GitHub issue #220 - Worktree setup hook for injecting
local configurations.
When polecats are spawned, their worktrees are created from the rig's
repo. Previously, there was no way to inject custom configurations
during this process.
Now users can place executable hooks in <rig>/.runtime/setup-hooks/
to run custom scripts during worktree creation:
rig/
.runtime/
setup-hooks/
01-git-config.sh <- Inject git config
02-copy-secrets.sh <- Copy secrets
99-finalize.sh <- Final setup
Features:
- Hooks execute in alphabetical order
- Non-executable files are skipped with a warning
- Hooks run with worktree as working directory
- Environment variables: GT_WORKTREE_PATH, GT_RIG_PATH
- Hook failures are non-fatal (warn but continue)
Example hook to inject git config:
#!/bin/sh
git config --local user.signingkey ~/.ssh/key.asc
git config --local commit.gpgsign true
Related to: hq-fq2zg, GitHub issue #220
* fix(lint): remove unused error return from buildCVSummary
buildCVSummary always returned nil for its error value, causing
golangci-lint to fail with "result 1 (error) is always nil".
The function handles errors internally by returning partial data,
so the error return was misleading. Removed it and updated caller.
1. TestQuerySessionEvents_FindsEventsFromAllLocations
- Skip test when running inside Gas Town workspace to prevent
daemon interaction causing hangs
- Add filterGTEnv helper to isolate subprocess environment
2. TestAddWithOptions_HasAgentsMD / TestAddWithOptions_AgentsMDFallback
- Create origin/main ref manually after adding local directory as
remote since git fetch doesn't create tracking branches for local
directories
Refs: gt-zbu3x
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd delete --hard --force creates tombstones instead of truly deleting,
which blocks agent bead recreation when polecats are respawned with the
same name. The tombstone is invisible to bd show/reopen but still
triggers UNIQUE constraint on create.
Workaround: Use CloseAndClearAgentBead instead of DeleteAgentBead when
cleaning up agent beads. Closed beads can be reopened by
CreateOrReopenAgentBead.
Changes:
- Add CloseAndClearAgentBead() for soft-delete that allows reopen
- Clears mutable fields (hook_bead, active_mr, cleanup_status, agent_state)
in description before closing to emulate delete --force --hard
- Update RemoveWithOptions to use close instead of delete
- Update RepairWorktreeWithOptions similarly
- Add comprehensive tests documenting the bd bug and verifying the workaround
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ZFC violation: InUse was being persisted to JSON and loaded from disk,
but Reconcile() immediately overwrites it with filesystem-derived state.
Changes:
- Mark InUse with json:"-" to exclude from serialization
- Load() now initializes InUse as empty (derived via Reconcile)
- Updated test to verify OverflowNext persists but InUse does not
Per ZFC "Discover, Don't Track", InUse should always be derived from
existing polecat directories, not tracked as separate state.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix misleading language that could suggest polecats wait in an idle pool:
- refinery/engineer.go: "available polecat" → "fresh polecat (spawned on demand)"
- namepool.go: Clarify this pools NAMES not polecats; polecats are spawned
fresh and nuked when done, only name slots are reused
- dog-pool-architecture.md: "Pool allocation pattern" → "Name slot allocation
pattern (pool of names, not instances)"
There is no idle pool of polecats. They are spawned for work and nuked when done.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Polecats have exactly three operating conditions - there is no idle pool:
- Working: session active, doing assigned work
- Stalled: session stopped unexpectedly, never nudged back
- Zombie: gt done called but cleanup failed
Key clarifications:
- These are SESSION states; polecat identity persists across sessions
- "Stalled" and "zombie" are detected conditions, not stored states
- The status:idle label only applies to persistent agents, not polecats
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two tests:
- TestAddWithOptions_HasAgentsMD: verifies AGENTS.md exists in worktree
after creation when it's in git
- TestAddWithOptions_AgentsMDFallback: verifies fallback copy works when
AGENTS.md is not in git but exists in mayor/rig
Fixes: gt-sq1.3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When creating or repairing worktrees, if AGENTS.md doesn't exist after
checkout (e.g., stale fetch or local-only file), copy it from mayor/rig.
This ensures polecats always have the critical "land the plane" instructions.
Applied to both AddWithOptions and RepairWorktreeWithOptions for
consistency. Errors are non-fatal (warning only).
Fixes: gt-sq1.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bare clones don't have refs/remotes/origin/* populated by default.
The configureRefspec fix (a91e6cd6) set up the fetch config but didn't
actually run a fetch, leaving origin/main unavailable.
This caused polecat worktree creation to fail with:
fatal: invalid reference: origin/main
Fixes:
1. Add git fetch after configureRefspec in bare clone setup
2. Add fetch before polecat worktree creation (ensures latest code)
The second fix matches RepairWorktreeWithOptions which already had a fetch.
Related: #286
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Fix beads.run() to always explicitly set BEADS_DIR based on the working
directory or explicit override
- This prevents inherited environment variables (e.g., from mayor session
with BEADS_DIR=/home/erik/gt/.beads) from causing prefix mismatch errors
when creating agent beads for rigs
- Update polecat manager to use NewWithBeadsDir for explicitness
- Add comprehensive test coverage for BEADS_DIR routing and validation
- Add SessionLister interface for deterministic orphan session testing
Root cause: When BEADS_DIR was set in the parent environment, all bd
commands used the town database (hq- prefix) instead of the rig database
(gt- prefix), causing "prefix mismatch: database uses 'hq' but you
specified 'gt'" errors during polecat spawn.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a polecat is nuked and re-spawned with the same name, CreateAgentBead
fails with a UNIQUE constraint error because the old agent bead exists as
a tombstone.
This adds CreateOrReopenAgentBead that:
1. First tries to create the agent bead normally
2. If UNIQUE constraint fails, reopens the existing bead and updates fields
Updated both spawn paths in polecat manager to use the new function.
Fixes#332
Co-authored-by: Claude <noreply@anthropic.com>
When a rig is added with --branch <non-default>, polecats and dogs now
correctly create worktrees from origin/<configured-branch> instead of
always using main/HEAD.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 of dynamic priming subsystem:
1. PRIME.md provisioning for all workers (hq-5z76w, hq-ukjrr Part A)
- Added ProvisionPrimeMD to beads package with Gas Town context template
- Provision at rig level in AddRig() so all workers inherit it
- Added fallback provisioning in crew and polecat managers
- Created PRIME.md for existing rigs
2. Post-handoff detection to prevent handoff loop bug (hq-ukjrr Part B)
- Added FileHandoffMarker constant (.runtime/handoff_to_successor)
- gt handoff writes marker before respawn
- gt prime detects marker and outputs "HANDOFF COMPLETE" warning
- Marker cleared after detection to prevent duplicate warnings
3. Priming health checks for gt doctor (hq-5scnt)
- New priming_check.go validates priming subsystem configuration
- Checks: SessionStart hook, gt prime command, PRIME.md presence
- Warns if CLAUDE.md is too large (should be bootstrap pointer)
- Fixable: provisions missing PRIME.md files
This ensures crew workers get Gas Town context (GUPP, hooks, propulsion)
even if the gt prime hook fails, via bd prime fallback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed the pending.json file that shadowed observable state. Now
discovers pending spawns directly from POLECAT_STARTED messages in
the Deacon's inbox.
Changes:
- CheckInboxForSpawns: Discovers from mail, no more LoadPending/SavePending
- TriggerPendingSpawns: Archives mail after successful trigger
- PruneStalePending: Archives old messages instead of pruning from JSON
The mail system is now the source of truth for pending spawns.
Closes: hq-i31f7
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create centralized AgentEnv function as single source of truth for all
agent environment variables. All agents now consistently receive:
- GT_ROLE, BD_ACTOR, GIT_AUTHOR_NAME (role identity)
- GT_ROOT, BEADS_DIR (workspace paths)
- GT_RIG, GT_POLECAT/GT_CREW (rig-specific identity)
- BEADS_AGENT_NAME, BEADS_NO_DAEMON (beads config)
- CLAUDE_CONFIG_DIR (optional account selection)
Remove RoleEnvVars in favor of AgentEnvSimple wrapper.
Remove IncludeBeadsEnv flag - beads env vars always included.
Update all manager and cmd call sites to use AgentEnv.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, polecat startup used hardcoded paths for BEADS_DIR that
didn't follow redirects for repos with tracked beads. This meant
polecats working in worktrees (where .beads/redirect points to the
actual beads location) would use the wrong beads directory.
Fixed locations:
- daemon.go: polecat startup now uses ResolveBeadsDir
- polecat/session_manager.go: session startup now uses ResolveBeadsDir
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Coordination section with gt nudge command
- Clarify line 180: routine nudging is Witness job, Mayor can nudge stuck refinery/witness
- Add warning to NEVER use tmux send-keys (drops Enter key)
- Includes liftoff test timestamp in manager.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agent sessions would fail on startup because send-keys arrived before the
shell was ready, causing 'bad pattern' and 'command not found' errors.
Fix: Create sessions with the command directly using tmux new-session's
command argument. This runs the agent as the pane's initial process,
avoiding shell readiness timing issues entirely.
Updated all agent managers: mayor, deacon, witness, refinery, polecat, crew.
Also fixes pre-existing build error in polecat/manager.go (polecatPath →
clonePath/newClonePath).
Closes#280
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes polecat worktree structure from:
polecats/<name>/
to:
polecats/<name>/<rigname>/
This gives Claude Code agents a recognizable directory name (e.g., tidepool/)
in their cwd instead of just the polecat name, preventing confusion about
which repo they are working in.
Key changes:
- Add clonePath() method to manager.go and session_manager.go for the actual
git worktree path, keeping polecatDir() for existence checks
- Update Add(), RepairWorktree(), Remove() to use new structure
- Update daemon lifecycle and restart code for new paths
- Update witness handlers to detect both structures
- Update doctor checks (rig_check, branch_check, config_check,
claude_settings_check) for backward compatibility
- All code includes fallback to old structure for existing polecats
Fixes#283
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds support for alternative AI runtime backends (Codex, OpenCode) alongside
the default Claude backend through a runtime abstraction layer.
- internal/runtime/runtime.go - Runtime-agnostic helper functions
- Extended RuntimeConfig with provider-specific settings
- internal/opencode/ for OpenCode plugin support
- Updated session managers to use runtime abstraction
- Removed unused ensureXxxSession functions
- Fixed daemon.go indentation, updated terminology to runtime
Backward compatible: Claude remains default runtime.
Co-Authored-By: Ben Kraus <ben@cinematicsoftware.com>
Co-Authored-By: Cameron Palmer <cameronmpalmer@users.noreply.github.com>
Two improvements:
1. gt crew start now infers rig from cwd when first arg is not a valid
rig name (gt-czltv). Previously, running `gt crew start bob` from
within a rig directory would fail because "bob" was treated as the
rig name. Now it checks if the arg is a valid rig first.
2. Refactored copyOverlay to shared rig.CopyOverlay utility:
- Eliminates code duplication between crew and polecat managers
- Preserves source file permissions instead of hardcoding 0644
- Follows PR #278 improvements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add overlay directory support to automatically copy gitignored files
(like .env, config files) from <rig>/.runtime/overlay/ to polecat
and crew worktree roots when they are spawned.
This allows services started by polecats/crew to have their required
configuration files at the root without committing them to git.
Changes:
- Add copyOverlay() function to polecat and crew managers
- Call copyOverlay() after setupSharedBeads() in AddWithOptions/RepairWorktreeWithOptions
- Non-fatal: overlay copy failures only log warnings, don't block spawn
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add WaitForShellReady call before SendKeys in all agent managers
(deacon, mayor, witness, refinery). This prevents intermittent
"can't find pane" errors that occur when the tmux session is
created but the shell isn't ready to receive input yet.
The issue manifests under load (e.g., during `gt up` when multiple
agents start in sequence) where the 200ms delay in SendKeysDelayed
isn't sufficient for the pane to be fully initialized.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
TestGetReturnsWorkingWithoutBeads assumes bd is not available and
expects state to default to StateWorking. When bd is installed, it
actually queries beads and returns the real state, causing the test
to fail.
Skip the test when bd is detected to avoid environment-dependent
failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Create mayor.Manager for mayor lifecycle (Start/Stop/IsRunning/Status)
- Create deacon.Manager for deacon lifecycle with respawn loop
- Move session.Manager to polecat.SessionManager (clearer naming)
- Add zombie session detection for mayor/deacon (kills tmux if Claude dead)
- Remove duplicate session startup code from up.go, start.go, mayor.go
- Rename sessMgr -> polecatMgr for consistency
- Make witness/refinery SessionName() public for status display
All agent types now follow the same Manager pattern:
mgr := agent.NewManager(...)
mgr.Start(...)
mgr.Stop()
mgr.IsRunning()
mgr.Status()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete the "discover, don't track" refactoring:
- checkGUPPViolations: use tmux.IsClaudeRunning() instead of agent_state
- checkOrphanedWork: derive dead agents from tmux, not agent_state=dead
- assessStaleness: rely on HasActiveSession (tmux), not agent_state
Non-observable states (stuck, awaiting-gate) are still respected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: Beads redirect architecture for tracked and local beads
This change implements proper redirect handling so that all rig agents
(Witness, Refinery, Crew, Polecats) can work with both:
- Tracked beads: .beads/ checked into git at mayor/rig/.beads
- Local beads: .beads/ created at rig root during gt rig add
Key changes:
1. SetupRedirect now handles tracked beads by skipping redirect chains.
The bd CLI doesn't support chains (A→B→C), so worktrees redirect
directly to the final destination (mayor/rig/.beads for tracked).
2. ResolveBeadsDir is now used consistently in polecat and refinery
managers instead of hardcoded mayor/rig paths.
3. Rig-level agents (witness, refinery) now use rig beads with rig
prefix instead of town beads. This follows the architecture where
town beads are only for Mayor/Deacon.
4. prime.go simplified to always use ../../.beads for crew redirects,
letting rig-level redirect handle tracked vs local routing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(doctor): Add beads-redirect check for tracked beads
When a repo has .beads/ tracked in git (at mayor/rig/.beads), the rig root
needs a redirect file pointing to that location. This check:
- Detects missing rig-level redirect for tracked beads
- Verifies redirect points to correct location (mayor/rig/.beads)
- Auto-fixes with 'gt doctor --fix'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Handle fileLock.Unlock error in daemon
Wrap fileLock.Unlock() return value to satisfy errcheck linter.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Fixes gt-v07fl: Polecat lifecycle cleanup for stale worktrees and git
tracking conflicts.
Changes:
1. Add .claude/ to .gitignore (prevents untracked file accumulation)
2. Add beads runtime state patterns to .gitignore (prevents future tracking)
3. Remove .beads/ runtime state from git tracking (mq/, issues.jsonl, etc.)
- Formulas and config remain tracked (needed for go install)
- Created follow-up gt-mpyuq for formulas refactor
4. Add DetectStalePolecats() to polecat manager for identifying cleanup candidates
5. Add CountCommitsBehind() to git package for staleness detection
6. Add `gt polecat stale <rig>` command for stale polecat detection/cleanup
- Shows polecats without active sessions
- Identifies polecats far behind main (configurable threshold)
- Optional --cleanup flag to auto-nuke stale polecats
The existing `gt polecat gc` command handles branch cleanup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a typed CleanupStatus with constants:
- CleanupClean, CleanupUncommitted, CleanupStash, CleanupUnpushed, CleanupUnknown
Adds helper methods:
- IsSafe(): true for clean status
- RequiresRecovery(): true for uncommitted/stash/unpushed
- CanForceRemove(): true if force flag can bypass
Updated files to use the new type:
- internal/polecat/types.go: Type definition and methods
- internal/polecat/manager.go: Validation logic
- internal/witness/handlers.go: Nuke safety checks
- internal/cmd/done.go: Status reporting
- internal/cmd/polecat.go: Recovery status checks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When repairing a stale polecat worktree, start from origin/<default-branch>
instead of the bare repo's HEAD. This ensures repaired polecats have the
latest fetched commits rather than potentially stale code.
- Add WorktreeAddFromRef to git package for creating worktrees from a ref
- RepairWorktreeWithOptions now uses origin/<default-branch> as start point
- Respects rig's configured default branch (main, master, etc.)
Based on PR #112 by markov-kernel. Test changes from that PR can be
submitted separately.
Closes#101🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: markov-kernel <markov-kernel@users.noreply.github.com>
The transient polecat model says: "Polecats exist only while working."
This removes the deprecated StateIdle and updates the codebase:
- Remove StateIdle from polecat/types.go (keep StateActive for legacy data)
- Update manager.go: Get() returns StateDone (not StateIdle) when no work
- Update manager.go: Add/Recreate return StateWorking (not StateIdle)
- Remove zombie scan logic from deacon.go (no idle polecats to scan for)
- Update tests to reflect new behavior
The correct lifecycle is now:
- Spawn: polecat created with work (StateWorking)
- Work: sessions cycle, sandbox persists
- Done: polecat signals completion (StateDone)
- Nuke: Witness destroys sandbox
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Clarify that this operation is for stale state recovery, not normal recycling:
- Recreate → RepairWorktree
- RecreateWithOptions → RepairWorktreeWithOptions
- Updated comments to explain this handles reconciliation when AllocateName
returns a name that already exists (stale state needing repair)
- Updated polecat_spawn.go output: Recreating → Repairing stale
- Updated gc command help text for consistency
The function is useful for atomic hook_bead setting during repair, so kept
rather than replacing with Remove + Add.
Fixes gt-l0lok
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These commands transitioned polecats to idle state, violating the transient
model. From PRIMING.md: "Polecats exist only while working. One task, then nuked."
Removed:
- gt polecat done - marked polecat as done and returned to idle
- gt polecat reset - force reset polecat to idle state
- gt polecat finish - alias for done
- gt polecat sleep - deprecated transition to done state
- gt polecat wake - deprecated transition to working state
- Manager.Finish() method
- Manager.Reset() method
- Manager.Wake() method
- Manager.Sleep() method
The correct model is: polecats use 'gt done' which signals Witness for nuke.
There is no "return to idle" - only death.
(gt-32d4a)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrate all role bead references from gt-*-role to hq-*-role using
beads.RoleBeadIDTown() function. Role beads are stored in town beads
(~/gt/.beads/) with the hq- prefix.
Changes:
- internal/cmd/prime.go: Use RoleBeadIDTown() for all roles
- internal/doctor/agent_beads_check.go: Use RoleBeadIDTown() for rig agents
- internal/polecat/manager.go: Use RoleBeadIDTown("polecat")
- internal/cmd/crew_add.go: Use RoleBeadIDTown("crew")
- internal/beads/beads.go: Update comments to document hq- convention
- Templates: Update bd show gt-deacon to bd show hq-deacon
Note: Tmux session names remain as gt-* (runtime identifiers).
Bead IDs use hq-* for town-level agents (persistent storage).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When creating agent beads for polecats or crew workers, the code was
using the rig root path (e.g., ~/gt/infra-dashboard/) instead of the
mayor/rig path where the actual beads database lives.
The rig root .beads/ directory only contains config.yaml with no
database. When bd runs from there, it walks up the directory tree
and finds the town-level beads database (with 'gm' prefix) instead
of the rig's database (with the rig's prefix like 'id'). This causes
prefix mismatch errors:
Error: prefix mismatch: database uses 'gm' but you specified 'id'
The routes.jsonl file maps rig prefixes to <rig>/mayor/rig, so the
code should always use that path for beads operations.
Changes:
- polecat/manager.go: Always use mayor/rig path, remove fallback logic
- cmd/crew_add.go: Use mayor/rig path instead of rig root
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- gt install now creates ~/gt/.claude/commands/ with all commands
- Removed per-workspace provisioning from crew/polecat managers
- Updated bd doctor to check town-level instead of per-workspace
- All agents inherit via Claude directory traversal
This eliminates duplicate /handoff skills in the picker.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When adding a crew member with 'gt crew add' or spawning a polecat,
provision the .claude/commands/ directory with standard slash commands
like /handoff. This ensures all agents have Gas Town utilities even if
the source repo does not have them tracked.
Changes:
- Add embedded commands templates (internal/templates/commands/)
- Add ProvisionCommands() to templates package
- Call ProvisionCommands from crew and polecat managers
- Add gt doctor commands-provisioned check with --fix support
Route to the correct beads location based on whether the source repo
has .beads/ tracked in git:
- If source has .beads/ tracked: route to mayor/rig/.beads
- Otherwise: route to rig root .beads/ (created by initBeads)
Updates both route registration in rig.go and polecat manager's
NewManager/setupSharedBeads to use consistent conditional logic.
When slinging work to a rig (auto-spawning a polecat), the hook_bead
is now set atomically during agent bead creation rather than in a
separate updateAgentHookBead call after spawn.
This fixes cross-beads routing issues when town beads (hq-*) are slung
to rig polecats (gt-* agent beads). By setting hook_bead at creation
time within the polecat manager context, the correct beads routing is
used.
Changes:
- Add AddOptions struct with HookBead field to polecat.Manager
- Add AddWithOptions() and RecreateWithOptions() functions
- Pass HookBead through SlingSpawnOptions in cmd/polecat_spawn.go
- Pass beadID as HookBead in cmd/sling.go for rig target spawns
Note: updateAgentHookBead() is kept for non-spawn targets (existing
agents) and formula-on-bead mode (updates hook to wisp root after
creation).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When spawning polecats in rigs with custom prefixes (e.g., beads uses bd-
instead of gt-), agent beads were being created with hardcoded gt- prefix,
causing warnings like issue ID gt-beads-polecat-obsidian does not match
configured prefix bd.
Changes:
- polecat/manager.go: agentBeadID() now looks up the rigs configured prefix
from routes.jsonl via beads.GetPrefixForRig()
- prime.go: getAgentBeadID() now uses prefix lookup for rig-level agents
(witness, refinery, polecat, crew)
Town-level agents (mayor, deacon) continue to use gt- prefix as expected.
Same fix as crew: polecat manager was overwriting project CLAUDE.md with
Gas Town polecat context. Gas Town context is now injected ephemerally via
SessionStart hook (gt prime) only.
Removed installCLAUDETemplate function and associated tests.
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>
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>