The comment incorrectly referred to polecats without hooked work as "idle".
With the self-cleaning model, polecats self-nuke on completion - there are
no idle polecats. A polecat without work is orphaned (needs cleanup).
Closes: gt-0jn0k
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The swarm dispatch command now always spawns fresh polecats instead of
searching for idle ones to reuse. With the self-cleaning model, polecats
self-nuke when done - there are no idle polecats to reuse.
Closes: gt-h4yc3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a polecat runs `gt done` with COMPLETED status, it now nukes its own
worktree before exiting. This is the self-cleaning model - polecats clean
up after themselves, reducing Witness/Deacon cleanup burden.
The self-nuke is:
- Only attempted for polecats (not Mayor/Witness/Deacon/Refinery)
- Only on COMPLETED status (not ESCALATED/DEFERRED)
- Non-fatal: if it fails, Witness will handle cleanup
Closes: gt-fqcst
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BeadsPath() was incorrectly returning <rig>/mayor/rig when HasMayor was
true, bypassing the redirect system at <rig>/.beads/redirect. This caused
beads operations to fail when the user's repo doesn't have tracked beads.
The redirect architecture is:
- <rig>/.beads/redirect -> mayor/rig/.beads (when repo tracks .beads/)
- <rig>/.beads/ contains local database (when repo doesn't track .beads/)
By always returning the rig root, all callers now go through the redirect
system which is set up by initBeads() during rig creation.
Affected callers (all now work correctly):
- internal/refinery/manager.go - Queue() for merge requests
- internal/swarm/manager.go - swarm operations
- internal/cmd/swarm.go - swarm CLI commands
- internal/cmd/status.go - rig status display
- internal/cmd/mq_next.go - merge queue operations
- internal/cmd/mq_list.go - merge queue listing
- internal/cmd/rig_dock.go - dock/undock operations
Fixes#317
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gt done now always exits the session. The --exit flag is removed since
exit is the only sensible behavior - polecats don't stay alive after
signaling completion.
Closes: gt-yrz4k
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The --state flag is meant for quick state checks and cannot be
combined with --hook, --dry-run, or --explain flags.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract prime.go into focused files:
- prime_session.go: session ID handling, hooks, persistence
- prime_output.go: all output/rendering functions
- prime_molecule.go: molecule workflow context
- prime_state.go: handoff markers, session state detection
Main prime.go now ~730 lines with core flow visible as "table of contents".
No behavior changes - pure file organization following Go idioms.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
IsClaudeRunning now checks for child processes when the pane command is
a shell (bash/zsh). This fixes gt crew start --all killing running crew
members that were started with "export ... && claude ..." commands.
Co-Authored-By: Claude Opus 4.5 <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>
The witness manager was using rig-level beads path to look up role
configuration, but role beads use the hq- prefix and live in town-level
beads. This caused "unexpected end of JSON input" errors when starting
witnesses because the rig database (with gt- prefix) couldn't find
hq-witness-role.
Changed roleConfig() to use townRoot instead of rig.BeadsPath() to
correctly resolve town-level role beads.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
CreateAgentBead was creating beads with only --labels=gt:agent but
bd create defaults to --type=task. The bd slot set command requires
type=agent to set slots, causing warnings during gt install and
gt rig add.
Fixes#315
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AGENTS.md had grown to 50 lines (above the 20-line bootstrap pointer
threshold) after dependency management docs were added in commit 14085db3.
The "Landing the Plane" and "Dependency Management" content belongs in
role templates (injected by gt prime), not in the on-disk bootstrap pointer.
This completes the fix for #316 - the AGENTS.md issue was caused by the
source repo having a large AGENTS.md that got cloned into rigs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fresh installs and rig adds were creating full CLAUDE.md files (285 lines
for mayor, ~100 lines for other roles), causing gt doctor to fail the
priming check immediately.
Per the priming architecture, CLAUDE.md should be a minimal bootstrap
pointer (<30 lines) that tells agents to run gt prime. Full context is
injected ephemerally at session start.
Changes:
- install.go: createMayorCLAUDEmd now writes 12-line bootstrap pointer
- manager.go: createRoleCLAUDEmd now writes role-specific bootstrap pointers
for mayor, refinery, crew, and polecat roles
Note: The AGENTS.md issue mentioned in #316 could not be reproduced - the
code does not appear to create AGENTS.md at rig level. May be from an older
version or different configuration.
Partial fix for #316
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Polecats were burning 48k+ tokens on exploratory work when spawned because
the startup beacon was informational-only. By the time the propulsion nudge
arrived 2 seconds later, the agent had already started exploring.
The handoff topic already had explicit instructions; this adds the same
pattern for assigned work: "Work is on your hook. Run gt hook now."
Fixes#319
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add t.Parallel() calls across config and rig test files to enable
concurrent test execution and faster test runs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add three new flags to gt prime command:
- --state: Output role state as JSON and exit early (for scripting)
- --dry-run: Skip side effects (persistence, locks, events)
- --explain: Show verbose role detection reasoning
The --state flag is mutually exclusive with all other flags and errors
if combined. The other flags (--dry-run, --explain, --hook) can be
combined freely.
Also fixes missing filepath import in beads.go.
Closes: bd-t8ven
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The AGENTS.md file at rig level (e.g., gastown/AGENTS.md) should be a thin
bootstrap pointer (<20 lines), not full context. This adds a check in
checkRigPriming() to flag large AGENTS.md files, similar to how CLAUDE.md
is checked in checkAgentPriming().
Also fixes missing filepath import in beads.go that was breaking the build.
Closes: bd-mfrs6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
detectSessionState() and checkSlungWork() both contained identical
logic for finding hooked/in_progress beads assigned to an agent.
Extracted this into findHookedBead() helper function.
Also includes priming subsystem improvements from mayor:
- Add --dry-run flag for testing without side effects
- Add --state flag to output detected state only
- Add --explain flag to show why sections are included
- Add missing filepath import to beads.go
Fixes: bd-hvwnb
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>
When `gt formula run` fell back to the default "gastown" rig (because no
rig could be detected), it didn't set rigPath, which meant the default
formula lookup would fail. Now rigPath is properly constructed when we
have townRoot but can't detect a current rig.
Also adds tests for GetDefaultFormula helper.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow `gt formula run` to be called without a formula name by configuring
a default in the rig's settings/config.json under workflow.default_formula.
Co-authored-by: Brett VanderVeen <brett.vanderveen@gfs.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When a session starts via handoff, the nudge message now includes
clear instructions to check hook and mail. This prevents agent
confusion when SessionStart hooks haven't loaded CLAUDE.md yet.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Import beads' UX design system into gastown:
- Add internal/ui/ package with Ayu theme colors and semantic styling
- styles.go: AdaptiveColor definitions for light/dark mode
- terminal.go: TTY detection, NO_COLOR/CLICOLOR support
- markdown.go: Glamour rendering with agent mode bypass
- pager.go: Smart paging with GT_PAGER support
- Add colorized help output (internal/cmd/help.go)
- Group headers in accent color
- Command names styled for scannability
- Flag types and defaults muted
- Add gt thanks command (internal/cmd/thanks.go)
- Contributor display with same logic as bd thanks
- Styled with Ayu theme colors
- Update gt doctor to match bd doctor UX
- Category grouping (Core, Infrastructure, Rig, Patrol, etc.)
- Semantic icons (✓ ⚠ ✖) with Ayu colors
- Tree connectors for detail lines
- Summary line with pass/warn/fail counts
- Warnings section at end with numbered issues
- Migrate existing styles to use ui package
- internal/style/style.go uses ui.ColorPass etc.
- internal/tui/feed/styles.go uses ui package colors
Co-Authored-By: SageOx <ox@sageox.ai>
hq-hcil1: Remove deprecated HasConflict/HasAuthFailure/IsNotARepo/HasRebaseConflict
methods that violated ZFC by having Go code decide error types based on stderr parsing.
Changes:
- Remove deprecated helper methods from GitError and SwarmGitError
- Export GetConflictingFiles() which uses git porcelain output (diff --diff-filter=U)
- Update CheckConflicts(), engineer.go, and integration.go to use GetConflictingFiles()
- Update tests to verify raw stderr is available for agent observation
ZFC principle: Go code transports raw output to agents; agents observe and decide.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply ZFC (Zero Forge Cache) principle across git error handling and
feed curation. Agents now observe raw git output and make their own
decisions rather than relying on pre-interpreted error types.
- Add GitError type with raw stdout/stderr for observation
- Add SwarmGitError following the same pattern
- Remove in-memory deduplication maps from Curator
- Curator now reads state from feed/events files
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>
hq-u0ach: done.go - Add --cleanup-status flag so agents can pass cleanup
status directly. Removes computeCleanupStatus() which violated ZFC by
having Go compute cleanup status from git state.
hq-z0zqw: beads.go - Remove strings.Contains parsing for ErrNotARepo and
ErrSyncConflict. Per ZFC, Go should transport errors to agents, not parse
them to make decisions. IsBeadsRepo() now uses file existence check.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a bead is closed externally via bd close, it could remain on
an agent's hook, causing confusion when running gt hook. Now
gt hook detects closed beads and shows a warning message with
instructions to clear the hook using gt unsling.
Closes: gt-8w0r6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The gt hook command wasn't finding hooked beads for town-level roles
(mayor, deacon) because of an identity format mismatch:
- When hooking a bead, resolveSelfTarget() sets assignee with trailing
slash (e.g., "mayor/")
- When querying, buildAgentIdentity() returned without slash ("mayor")
This caused the assignee filter to miss the hooked bead since bd does
exact matching on the assignee field.
Fix:
- Update buildAgentIdentity() to return "mayor/" and "deacon/" with
trailing slash, matching the format used when setting assignee
- Update isTownLevelRole() to accept both formats for compatibility
Fixes: gt-g6ng2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two fixes in this commit:
1. daemon/lifecycle.go: Fix agent bead ID pattern for GUPP/orphaned work checks
- Wrong: gt-polecat-<rig>-<name> (e.g., gt-polecat-gastown-nux)
- Correct: <prefix>-<rig>-polecat-<name> (e.g., gt-gastown-polecat-nux)
- Use config.GetRigPrefix() instead of hardcoding gt prefix
- Use beads.ParseAgentBeadID() in extractRigFromAgentID
2. beads/beads.go: Fix invalid --add-label flag in bd create calls
- bd create uses --labels, not --add-label
- bd update uses --add-label (unchanged, was correct)
- Fixed Create, CreateWithID, CreateAgentBead, CreateRigBead
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two ZFC fixes:
1. Boot marker file (hq-zee5n): Changed IsRunning() to query
tmux.HasSession() directly instead of checking marker file
freshness with TTL. Removed stale marker check from doctor.
2. Branch pattern matching (hq-zwuh6): Replaced hardcoded "polecat/"
strings with constants.BranchPolecatPrefix for consistency.
Also removed 60-second WaitForCommand blocking from crew Start()
which was causing gt crew start to hang.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per ZFC principle: 'Let agents decide thresholds. Stuck is a judgment call.'
Changes:
- Add health check threshold fields to RoleConfig (ping_timeout,
consecutive_failures, kill_cooldown, stuck_threshold)
- Add LoadStuckConfig() to read thresholds from hq-deacon-role bead
- Update patrol_check.go to use configurable stuck threshold
- Defaults remain as fallbacks when no role bead config exists
Agents can now configure their stuck detection by adding fields to their
role bead, e.g.:
ping_timeout: 45s
consecutive_failures: 5
kill_cooldown: 10m
stuck_threshold: 2h
Fixes: hq-2355b
Replace ProcessExists() checks in witness and refinery managers with
tmux session detection. Agent liveness should be derived from tmux
session state, not PID probing (per ZFC tracking principles).
- Remove util.ProcessExists() from witness/manager.go and refinery/manager.go
- Delete internal/util/process.go and process_test.go (now unused)
- Foreground mode and Stop() now rely solely on tmux HasSession/KillSession
Closes: hq-yxkdr (recentDeaths already removed)
Closes: hq-1sd4o (ProcessExists removed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extends the --agent flag with a more general --env flag that allows
setting arbitrary environment variables when starting a witness.
Precedence (highest to lowest):
1. CLI --env overrides
2. Role bead env_vars
3. config.AgentEnv() defaults
Examples:
gt witness start greenplace --env ANTHROPIC_MODEL=claude-3-haiku
gt witness restart greenplace --env DEBUG=1 --env VERBOSE=true
Co-authored-by: joshuavial <git@codewithjv.com>
Introduces config.AgentEnv() as the single source of truth for all agent
environment variables. Previously, different roles received different subsets
of variables depending on their startup path.
Changes:
- All agents now receive GT_ROOT and BEADS_DIR (previously only polecat/refinery)
- Add gt doctor env-vars check to validate tmux session variables
- Fix gt role home witness returning incorrect path
- Fix BEADS_DIR not following redirects for repos with tracked beads
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github.com>