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>
Clarifies the three distinct lifecycle layers to prevent confusion:
- Session (Claude context): ephemeral, cycles per step
- Sandbox (worktree): persistent until nuke
- Slot (name from pool): persistent until nuke
Addresses anti-patterns like "idle polecats" and misunderstanding
what recycling means. (gt-bc6gm)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --branch flag to `gt rig add` to specify a custom default branch
instead of auto-detecting from remote. This supports repositories that
use non-standard default branches like `develop` or `release`.
Changes:
- Add --branch flag to `gt rig add` command
- Store default_branch in rig config.json
- Propagate default branch to refinery, witness, daemon, and all commands
- Rename ensureMainBranch to ensureDefaultBranch for clarity
- Add Rig.DefaultBranch() method for consistent access
- Update crew/manager.go and swarm/manager.go to use rig config
Based on PR #49 by @kustrun - rebased and extended with additional fixes.
Co-authored-by: kustrun <kustrun@users.noreply.github.com>
🤖 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 a polecat worker is recycled via RecreateWithOptions, it now starts
from the latest fetched origin/<default-branch> instead of the stale HEAD.
Previously, `WorktreeAdd` created branches from the current HEAD, but after
fetching, HEAD still pointed to old commits. The new `WorktreeAddFromRef`
method allows specifying a start point (e.g., "origin/main").
Fixes#101
- Add mutex protection for global registry state
- Cache loaded config paths to avoid redundant file reads
- Add ResetRegistryForTesting() for test isolation
- Add BuildResumeCommand() for agent-specific session resume
- Add SupportsSessionResume() and GetSessionIDEnvVar() helpers
Fixes: gt-sn610, gt-otgn3, gt-r2eg1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Witness lifecycle was not reliably killing polecat tmux sessions after
POLECAT_DONE. Sessions were piling up because gt polecat nuke may fail to
kill the session due to rig loading issues or race conditions with
IsRunning checks.
Fix: Kill the tmux session FIRST and unconditionally in NukePolecat,
before calling gt polecat nuke. This ensures the session is always killed
regardless of what happens in the downstream nuke command.
The session name pattern is deterministic (gt-<rig>-<polecat>), so we can
construct it directly from the rigName and polecatName parameters.
Fixes: gt-g9ft5
🤖 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>
- Use underscores instead of stripping invalid characters
- Convert suggestion to lowercase for consistency
- Explicitly state that underscores are allowed
Before: "MyProject.jl" → "MyProjectjl"
After: "MyProject.jl" → "myproject_jl"
Closes#97
Co-Authored-By: Olivier Debeuf De Rijcker <markov-kernel@users.noreply.github.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gt costs record now auto-detects the current tmux session when
running inside tmux, so the Stop hook no longer requires --session
flag or GT_SESSION env var.
Detection order:
1. --session flag
2. GT_SESSION env var
3. GT_RIG/GT_ROLE derivation
4. Current tmux session (new)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add syscall.Flock() exclusive lock in daemon.Run() to prevent TOCTOU
race condition where concurrent 'gt daemon start' commands could spawn
multiple daemons. Only the first to acquire the lock succeeds; others
exit cleanly. Lock is per-town (in townRoot/daemon/daemon.lock) so
multiple GT instances from different directories work independently.
Also detect race losers in runDaemonStart() by comparing spawned PID
with PID file, reporting 'already running' instead of false success.
Implements agent abstraction layer to support multiple AI coding agents.
Built-in presets (E2E tested):
- Claude Code (default)
- Gemini CLI
- OpenAI Codex
Key changes:
- Add AgentRegistry with built-in presets and custom agent support
- Add TownSettings with default_agent and custom agents map
- Add Agent field to RigSettings for per-rig agent selection
- Update ResolveAgentConfig for hierarchical config resolution
- Update spawn paths to use configured agent instead of hardcoded claude
Configuration hierarchy (first match wins):
1. Rig's Runtime config (backwards compat)
2. Rig's Agent -> custom agents -> built-in presets
3. Town's default_agent setting
4. Fallback to Claude
Additional agents (aider, opencode, etc.) can be added via config file:
settings/agents.json
Addresses Issue #10: Agent Agnostic Engine with Multi-provider support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add TownBeadsPrefix constant to agent_ids.go to centralize the "hq"
prefix string used for town-level agent beads. This makes prefix
changes easier and reduces string duplication.
Also update agent_beads_check.go to use the helper functions instead
of hardcoded strings for consistency.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a const TownBeadsPrefix = "hq" to centralize the town-level
beads prefix. Updates all hq- string literals in agent_ids.go to use
the constant, making prefix changes easier and reducing duplication.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Explain why agent bead creation failures are hard errors while role bead
creation failures are soft errors (log and continue).
Agent beads are identity beads that form the CV/reputation ledger foundation.
Role beads are documentation templates not required for agent operation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The isFirstRig parameter was no longer used - it was being assigned
to a blank identifier. Since initAgentBeads is an internal function
with only 2 callers in this repo, remove the parameter entirely.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Dog role bead creation to the roleDefs slice, ensuring Dog
agents have their role definition created during gt install.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agent directories (witness/, refinery/, mayor/) contained state.json files
with last_active timestamps that were never updated, making them stale and
misleading. This change removes:
- initAgentStates function that created vestigial state.json files
- AgentState type and related Load/Save functions from config package
- MayorStateValidCheck from doctor checks
- requesting_* lifecycle verification (dead code - flags were never set)
- FileStateJSON constant and MayorStatePath function
Kept intact:
- daemon/state.json (actively used for daemon runtime state)
- crew/<name>/state.json (operational CrewWorker metadata)
- Agent state tracking via beads (the ZFC-compliant approach)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Install now detects existing town-level agents via bd list to avoid relying on
bd show prefix matching, and the role slot test reads JSON from stdout only to
ignore stderr warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Install now creates town role beads before agents and only skips agent creation
when the exact agent bead exists, so role slots get set reliably. Add an
integration test that asserts role slots are populated after install.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The gt doctor patrol-hooks-wired check was recommending 'gt daemon init'
which doesn't exist. The daemon is auto-initialized when running
'gt daemon start', so that's the correct command to recommend.
Fixes#94🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The integration.yml was running ./... which includes beads tests that
require database initialization. Changed to match ci.yml's scope of
./internal/cmd/... which contains the actual integration tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The integration.yml workflow was missing the beads CLI installation
that the main ci.yml has. This caused integration tests to fail with
"beads dependency check failed".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds CI fix to run go generate before build steps.
- Adds claude.EnsureSettingsForRole() call in gt install after CLAUDE.md
- Adds go generate ./internal/formula/... to ci.yml (test, lint, integration jobs)
- Adds go generate ./internal/formula/... to integration.yml
The go generate step creates the embedded formula JSON files that are
gitignored but required for the go:embed directive in embed.go.
Fixes#84🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When users run `claude` directly at the town root instead of
`gt mayor start`, Claude wasn't receiving the Mayor delegation
protocol because `gt prime` never ran.
Root cause: `gt install` created CLAUDE.md but not the
.claude/settings.json with SessionStart hooks that run `gt prime`.
This adds `claude.EnsureSettingsForRole(absPath, "mayor")` to
`gt install` to ensure the Mayor always gets proper Claude settings
with hooks that enforce the delegation protocol.
Fixes#84🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, town-level session stopping (Mayor, Boot, Deacon) was
implemented inline in gt down with separate code blocks for each
session. The shutdown order (Boot must stop before Deacon to prevent
the watchdog from restarting Deacon) was implicit in the code ordering.
Add session.TownSessions() and session.StopTownSession() to centralize
town-level session management. This provides a single source of truth
for the session list, shutdown order, and graceful/force logic.
Refactor gt down to use these helpers instead of inline logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all callers of deprecated MayorBeadID()/DeaconBeadID() to use
MayorBeadIDTown()/DeaconBeadIDTown() which return hq- prefix IDs for
town-level beads storage.
Changes:
- internal/daemon/lifecycle.go: identityToAgentBeadID and checkStaleAgents
- internal/cmd/prime.go: getAgentBeadID
- internal/cmd/molecule_status.go: buildAgentBeadID
- internal/cmd/prime_test.go: update expected values to hq-*
- Comments updated to reflect hq- prefix for town-level agents
The deprecated functions remain for backward compatibility and are used
by the migration tool (migrate_agents.go).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 5 of epic gt-4r1ph (align agent/role beads with two-level architecture):
- Create docs/architecture.md with agent bead storage table documenting
the correct two-level architecture:
- Town beads (~/gt/.beads/): hq-mayor, hq-deacon, hq-*-role
- Rig beads (<rig>/.beads/): <prefix>-<rig>-witness, <prefix>-<rig>-refinery
- Update internal/rig/manager.go initAgentBeads() comments with MIGRATION
NOTEs explaining current state vs target architecture (gt-4r1ph)
- Close PR #50 with explanation that the fix direction was wrong
CLAUDE.md templates already correctly document hq-* for town beads and
project prefix for rig beads.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1: Create agent_ids.go with town-level bead ID helpers
- MayorBeadIDTown(), DeaconBeadIDTown(), DogBeadIDTown()
- RoleBeadIDTown() and role-specific helpers (hq-*-role)
- Add deprecation notices to old gt-* prefix functions
Phase 2: Create town-level agent beads during gt install
- initTownAgentBeads() creates hq-mayor, hq-deacon agent beads
- Creates role beads: hq-mayor-role, hq-deacon-role, etc.
- Update rig/manager.go to use rig beads for Witness/Refinery
This aligns with the two-level beads architecture:
- Town beads (~/gt/.beads/): hq-* prefix for Mayor, Deacon, roles
- Rig beads (<rig>/.beads/): <prefix>-* for Witness, Refinery, Polecats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement two-level beads architecture for agent lookups:
- Town-level agents (Mayor, Deacon) now use hq- prefix and are
looked up in town beads (~/.beads/)
- Rig-level agents continue using rig prefix (e.g., gt-) and are
looked up in rig beads
Changes:
- Add MayorBeadIDTown(), DeaconBeadIDTown(), DogBeadIDTown() helpers
- Add GetTownBeadsPath() for town beads path resolution
- Update gt status to pre-fetch town-level agent beads
- Update agentIDToBeadID() to use town-level IDs
- Update agent_beads_check.go to check/fix in correct tier
- Update agentAddressToIDs() in deacon.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new helper functions for town-level agent bead IDs:
- MayorBeadIDTown() → "hq-mayor"
- DeaconBeadIDTown() → "hq-deacon"
- DogBeadIDTown(name) → "hq-dog-<name>"
- RoleBeadIDTown(role) → "hq-<role>-role"
These use the hq- prefix for town-level beads storage, distinct from
the gt- prefix used for rig-level beads.
Mark MayorBeadID() and DeaconBeadID() as deprecated in favor of the
new *Town() variants.
(gt-y24km)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements Phase 4 of the two-level beads architecture migration:
- Add hq- prefix helper functions for town-level agent beads
- Add CreateWithID method for deterministic bead creation
- Create gt migrate-agents command with dry-run/execute modes
- Migrate gt-mayor/gt-deacon to hq-mayor/hq-deacon in town beads
- Migrate role beads (gt-*-role) to town beads (hq-*-role)
- Add migration labels to old beads for tracking
- Idempotent: skips already-migrated beads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When using gt sling with --quality=shiny, the mol bond command was
failing with "mol bond requires direct database access" error. This
was because bd daemon can be slow to start or unavailable, and mol
bond requires direct database access.
Fix: Added --no-daemon flag to the bd mol bond invocation in sling.go
at line 407. This bypasses the daemon and uses direct database access
for molecule bonding operations.
Fixes gt--4hz
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>