The Deacon patrol formula now clearly documents the continuous loop:
1. Execute patrol steps (inbox-check through context-check)
2. Squash wisp, wait for activity via await-signal (15min max)
3. Create new patrol wisp and hook it
4. Repeat from step 1
Changes:
- Formula description emphasizes CONTINUOUS EXECUTION with flow diagram
- loop-or-exit step renamed to "Continuous patrol loop" with explicit
instructions for creating/hooking new wisps after await-signal
- plugin-run step now clearly shows gt plugin list + gt dog dispatch
- Deacon role template updated to match formula changes
- Formula version bumped to 9
Fixes gt-fm2c: Deacon needs continuous patrol loop for plugin dispatch
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change molecule step completion instructions to use `gt mol step done`
instead of `bd close`. This ensures polecats get fresh context between
each step, which is critical for multi-step review workflows like
shiny-enterprise where each refinement pass should have unbiased attention.
The `gt mol step done` command already:
1. Closes the step
2. Finds the next ready step
3. Respawns the pane for fresh context
But polecats were being instructed to use `bd close` directly, which
skipped the respawn and let them run through entire workflows in a
single session with accumulated context.
Updated:
- prime_molecule.go: step completion instructions
- mol-polecat-work.formula.toml
- mol-polecat-code-review.formula.toml
- mol-polecat-review-pr.formula.toml
Fixes: hq-0kx7ra
vars.mode had both required=true and default="conservative", which
causes formula validation to fail with:
vars.mode: cannot have both required:true and default
This prevented gt doctor from dispatching cleanup work to dogs.
Remove required=true since the default value ensures the variable
is always populated.
Co-authored-by: mayor <ec2-user@ip-172-31-43-79.ec2.internal>
* Add hung-session-detection step to deacon patrol
Detects and surgically recovers Gas Town sessions where Claude API
call is stuck indefinitely. These appear "running" (tmux session
exists) but aren't processing work.
Safety checks (ALL must pass before recovery):
1. Session matches Gas Town pattern exactly (gt-*-witness, etc)
2. Session shows waiting state (Clauding/Deciphering/etc)
3. Duration >30min AND (zero tokens OR duration >2hrs)
4. NOT showing active tool execution (⏺ markers)
This closes a gap where existing zombie-scan only catches processes
not in tmux sessions.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(orphan): protect all tmux sessions, not just Gas Town ones
The orphan cleanup was killing Claude processes in user's personal tmux
sessions (e.g., "loomtown", "yaad") because only sessions with gt-* or
hq-* prefixes were protected.
Changes:
- Renamed getGasTownSessionPIDs() to getTmuxSessionPIDs()
- Now protects ALL tmux sessions regardless of name prefix
- Updated variable names for clarity (gasTownPIDs -> protectedPIDs)
The TTY="?" check is not reliable during certain operations (startup,
session transitions), so explicit protection of all tmux sessions is
necessary to prevent killing user's personal Claude instances.
Fixes#923
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: mayor <ec2-user@ip-172-31-43-79.ec2.internal>
Co-authored-by: Claude <noreply@anthropic.com>
Remove redundant routing rules and health check documentation
that was duplicating information available elsewhere.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add explicit routing rules to ping-deacon step:
- WITNESS_PING always goes to deacon/, never to mayor/
- Mayor only receives ALERT messages (Step 3)
- Define what 'healthy' looks like (idle at prompt is normal)
This prevents the witness LLM from misinterpreting the formula
and sending raw WITNESS_PING messages to mayor instead of deacon.
Fixes: gt-uvz90
Add three new verification legs to the code-review convoy formula:
- wiring: detects dependencies added but not actually used
- commit-discipline: reviews commit quality and atomicity
- test-quality: verifies tests are meaningful, not just present
Also adds presets for common review modes:
- gate: light review (wiring, security, smells, test-quality)
- full: all 10 legs for comprehensive review
- security-focused: security-heavy for sensitive changes
- refactor: code quality focus
This is a minimal subset of PR #4's Worker → Reviewer pattern,
focusing on the most valuable additions without Go code changes.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(formulas): replace hardcoded ~/gt/ paths with $GT_ROOT
Formula files contained hardcoded ~/gt/ paths that break when running
Gas Town from a non-default location (e.g., ~/gt-private/). This causes:
- Dogs stuck in working state (can't write to wrong path)
- Cross-town contamination when ~/gt/ exists as separate town
- Boot triage, deacon patrol, and log archival failures
Replaces all ~/gt/ and $HOME/gt/ references with $GT_ROOT which is
set at runtime to the actual town root directory.
Fixes#757
* chore: regenerate embedded formulas
Run go generate to sync embedded formulas with .beads/formulas/ source.
Key fix: Orphan cleanup now skips Claude processes in valid Gas Town
tmux sessions (gt-*/hq-*), preventing false kills of witnesses,
refineries, and deacon during startup.
Updated all component versions:
- gt CLI: 0.3.1 → 0.4.0
- npm package: 0.3.0 → 0.4.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add mol-backoff-test formula for integration testing exponential backoff
with short intervals (2s base, 10s max) to observe multiple cycles quickly.
Fix await-signal to use --since 1s when subscribing to activity feed.
Without this, historical events would immediately wake the signal,
preventing proper timeout and backoff behavior.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Polish help text across all agent commands to clarify roles:
- crew: persistent workspaces vs ephemeral polecats
- deacon: town-level watchdog receiving heartbeats
- dog: cross-rig infrastructure workers (cats vs dogs)
- mayor: Chief of Staff for cross-rig coordination
- nudge: universal synchronous messaging API
- polecat: ephemeral one-task workers, self-cleaning
- refinery: merge queue serializer per rig
- witness: per-rig polecat health monitor
Add comprehensive gt nudge documentation to crew template explaining
when to use nudge vs mail, common patterns, and target shortcuts.
Add orphan-process-cleanup step to deacon patrol formula to clean up
claude subagent processes that fail to exit (TTY = "?").
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cost tracking infrastructure works but has no data source:
- Claude Code displays costs in TUI status bar, not scrollback
- tmux capture-pane can't see TUI chrome
- All sessions show $0.00
Changes:
- Mark gt costs command as [DISABLED] with deprecation warnings
- Mark costs-digest patrol step as [DISABLED] with skip instructions
- Document requirement for Claude Code to expose CLAUDE_SESSION_COST
Infrastructure preserved for re-enabling when Claude Code adds support.
Ref: GH#24, gt-7awfjq
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per-cycle patrol digests were polluting JSONL with O(cycles/day) beads.
Apply the same pattern used for cost digests:
- Make per-cycle squash digests ephemeral (not exported to JSONL)
- Add 'gt patrol digest' command to aggregate into daily summary
- Add patrol-digest step to deacon patrol formula
Daily cadence reduces noise while preserving observability.
Closes: gt-nbmceh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a workflow formula for Gas Town releases with:
- Workspace preflight checks (uncommitted work, stashes, branches)
- CHANGELOG.md and info.go versionChanges updates
- Version bump via bump-version.sh
- Local install and daemon restart
- Error handling guidance for crew vs polecat execution
Adds supervision for dispatched dogs that may get stuck.
The new step (between dog-pool-maintenance and orphan-check):
- Lists dogs in "working" state
- Checks work duration vs plugin timeout (default 10m)
- Decision matrix based on how long overdue:
- < 2x timeout: log warning, check next cycle
- 2x-5x timeout: file death warrant
- > 5x timeout: force clear + escalate to Mayor
- Tracks chronic failures for repeat offenders
This closes the supervision gap where dogs could hang forever
after being dispatched via `gt dog dispatch --plugin`.
Closes: gt-s4dp3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add documentation to make the formula package more discoverable and
demonstrate its value as a reusable workflow definition library.
The formula package provides TOML-based workflow definitions with:
- Type inference (convoy, workflow, expansion, aspect)
- Comprehensive validation
- Cycle detection in dependency graphs
- Topological sorting (Kahn's algorithm)
- Ready-step computation for parallel execution
New files:
- doc.go: Package-level godoc with examples and API overview
- README.md: User guide with installation, quick start, and API reference
- example_test.go: Runnable examples for godoc and testing
The package has 130% test coverage (1,200 LOC tests for 925 LOC code)
and only depends on github.com/BurntSushi/toml.
- shiny.formula.toml: defers to role's git workflow instead of hardcoding PR
- crew.md.tmpl: checks remote origin ownership instead of absolute PR ban
- tmux.go: minor comment fix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Deacon patrol formula now uses `gt mol step await-signal` with
exponential backoff instead of vague "sleep 60s" instructions.
How it works:
- Subscribes to `bd activity --follow` (beads activity feed)
- Returns IMMEDIATELY when any gt/bd command triggers activity
- On timeout, waits exponentially longer: 60s → 120s → 240s → max 10m
- Tracks idle:N label on hq-deacon bead across invocations
This connects the designed-but-unintegrated backoff mechanism to the
actual patrol loop. Idle towns let Deacon sleep; active work wakes it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds the missing github-gate-check step that runs `bd gate discover` and
`bd gate check --type=gh` to evaluate GitHub CI gates. Updates
dispatch-gated-molecules to depend on both gate-evaluation and
github-gate-check.
Fixes: gt-sfxpr
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(costs): redesign session cost tracking with wisps and daily digests
Implement the wisp-based cost tracking architecture per gt-cm900:
- gt costs record now creates ephemeral wisps (not exported to JSONL)
to avoid log-in-database pollution with O(sessions/day) events
- gt costs digest aggregates yesterday's session wisps into a single
permanent "Cost Report YYYY-MM-DD" bead for audit purposes
- gt costs query updated: --today queries wisps, --week queries
digest beads + today's wisps
- gt costs migrate closes legacy open session.ended beads
- Deacon patrol formula updated with costs-digest step
The new architecture:
Session ends -> Wisp (fast, N/day) -> Patrol digest -> Bead (1/day)
This preserves audit trail while keeping issues.jsonl clean.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: sync canonical formula with embedded copy
Update .beads/formulas/ with the costs-digest step added to
mol-deacon-patrol.formula.toml. The go:generate copies from
.beads/formulas/ to internal/formula/formulas/.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When upgrading gt on an existing installation without .installed.json,
formulas that exist but don't match embedded were incorrectly marked as
"modified" (implying user customization). Now they're marked "untracked"
and are safe to update since there's no record of user modification.
This improves the upgrade experience:
- "modified" = tracked file user changed (skip update)
- "untracked" = file exists but not tracked (safe to update)
Adds 3 new tests for untracked scenarios.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds infrastructure to automatically update embedded formulas when
the binary is upgraded, while preserving user customizations.
Changes:
- Add CheckFormulaHealth() to detect outdated/modified/missing formulas
- Add UpdateFormulas() to safely update formulas via gt doctor --fix
- Track installed formula checksums in .beads/formulas/.installed.json
- Add FormulaCheck to gt doctor with auto-fix capability
- Compute checksums at runtime from embedded files (no build-time manifest)
Update scenarios:
- Outdated (embedded changed, user unchanged): Update automatically
- Modified (user customized): Skip with warning
- Missing (user deleted): Reinstall with message
- New (never installed): Install
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new step to mol-deacon-patrol.formula.toml that discovers molecules
blocked on gates that have now closed, and dispatches them to the
appropriate rig's polecat pool.
This completes the async resume cycle without explicit waiter tracking.
The molecule state IS the waiter - patrol discovers reality each cycle.
- Uses bd mol ready --gated to find gate-ready molecules
- Dispatches via gt sling <mol-id> <rig>/polecats
- Runs after gate-evaluation, before health-scan
- Bumps formula version to 6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The deacon tmux session is named hq-deacon, not gt-deacon. Fix the
incorrect references in mol-boot-triage and mol-gastown-boot formulas.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The formula parser only supports TOML (uses toml.Decode). The JSON
version of mol-gastown-boot was never used - it was likely created
by mistake or for an abandoned experiment.
Changes:
- Remove .beads/formulas/mol-gastown-boot.formula.json
- Remove internal/formula/formulas/mol-gastown-boot.formula.json
- Simplify go:generate to only copy .formula.toml files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Deacon patrol formula's zombie-scan step now:
- Only detects zombies via --dry-run, never kills directly
- Files death warrants for Boot to handle interrogation/execution
- Includes psychological weight language about termination gravity
This prevents accidental destruction of worker context, mid-task
progress, and unsaved state. Kill authority belongs to Boot.
Bumped version to 5.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Defines the state machine that Dogs execute for death warrants:
- 3-attempt interrogation with escalating timeouts (60s, 120s, 240s)
- PARDON path when session responds with ALIVE
- EXECUTE path after all attempts exhausted
- EPITAPH step for audit logging
Key design decisions documented:
- Dogs are goroutines, not Claude sessions
- Timeout gates close on timer OR early response detection
- State persisted to ~/gt/deacon/dogs/active/ for crash recovery
Implements specification for gt-cd404.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Regenerate formulas to sync with source templates
- Fix unparam lint warnings in status.go (unused townRoot parameters)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Additional cleanup from the agent_state refactoring:
- Remove dead code: checkStaleAgents(), markAgentDead() in lifecycle.go
- Remove dead code: reportAgentState(), getAgentFields() in prime.go
- Update getAgentBeadState() comment to clarify non-observable states only
- Update mol-witness-patrol.formula.toml to use tmux discovery
- Update mol-polecat-lease.formula.toml to use POLECAT_DONE mail
- Update docs/watchdog-chain.md to reflect new architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --verbose/-v flag to show detailed multi-line output (old behavior)
- Compact mode shows: name + status indicator (●/○) + hook + mail count
- MQ info displayed inline with refinery
- Fix Makefile install target to use ~/.local/bin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous commit (a3bccc8) violated ZFC by implementing molecule step logic
in Go handlers. Per PRIMING.md: Agent decides. Go transports.
This commit:
1. Reverts the gt witness process command (Go code should not make decisions)
2. Updates mol-witness-patrol formula with explicit CLI commands
3. Fixes --wisp to --ephemeral (bd create flag correction)
4. Removes --wisp from bd list calls (invalid flag)
The Witness Claude agent now has explicit instructions:
- Parse POLECAT_DONE message for polecat name
- Check cleanup_status via bd show
- Run gt polecat nuke or bd create --ephemeral based on status
- Archive mail after handling
ZFC: Agent decides. Go transports.
Add `gt deacon stale-hooks` command to find and unhook stale beads.
Problem: Beads can get stuck in 'hooked' status when agents die or
abandon work without properly unhooking.
Solution:
- New command scans for hooked beads older than threshold (default 1h)
- Checks if assignee agent is still alive (tmux session exists)
- Unhooks beads with dead agents (sets status back to 'open')
- Supports --dry-run to preview without making changes
Also adds "stale-hook-check" step to Deacon patrol formula.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added steps from discovered cleanup operations:
- clear-hooks: Detach all hooked work from agents
- reset-in-progress: Reset in-progress beads to open status
- burn-wisps: Clean up wisp directories and ephemeral beads
- validate-clean: Verify all cleanup operations succeeded
Updated existing steps with more detailed procedures.
Key principles preserved:
- No forcing, no lost work
- Idempotent (safe to run multiple times)
- Crew workers NOT affected (user-managed)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 3 of heresy correction: polecat branches stay local, Refinery
accesses them via shared .repo.git.
Changes:
- templates/polecat-CLAUDE.md: Remove push from completion checklist
- mol-polecat-work.formula.toml: Remove push step from cleanup-workspace
- polecat.md.tmpl: Update landing rule for local branches
- refinery.md.tmpl: Change origin/polecat to local branch references
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4 of local-only polecat branches: Handle conflict resolution edge case.
Problem: If polecat worktree is nuked before MR merges, the local branch
is gone and conflict resolution can't access it.
Solution: Witness now defers cleanup for polecats with pending MRs:
- HandlePolecatDone creates a cleanup wisp with "merge-requested" state
- Polecat worktree preserved until MERGED signal arrives
- HandleMerged then nukes the polecat (existing behavior)
Also updated mol-polecat-conflict-resolve.formula.toml:
- Removed fetch from origin (branches are local-only now)
- Added instructions to fetch from source polecat's worktree
- Added rig and source_polecat variables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Commit embedded formulas for go install @latest
The internal/formula/formulas/ directory was gitignored, causing
`go install github.com/steveyegge/gastown/cmd/gt@latest` to fail with:
pattern formulas/*.formula.json: no matching files found
The go:embed directive requires these files at build time, but
go install @latest doesn't run go:generate. By committing the
generated formulas, users can install directly without cloning.
Maintainers should run `go generate ./...` after modifying
.beads/formulas/ to keep the embedded copy in sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci: Add check for committed embedded formulas
Adds a new CI job that:
1. Builds without running go:generate (catches missing formulas)
2. Verifies committed formulas match .beads/formulas/ source
Also removes redundant go:generate steps from other jobs since
formulas are now committed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: exclude towers-of-hanoi test formulas from embed
These are durability stress test fixtures (pre-computed move sequences),
not production formulas users need. Excluding them reduces embedded
content by ~10K lines.
🤖 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>
Co-authored-by: gus <steve.yegge@gmail.com>
The hook query now falls back to checking in_progress beads assigned to the
agent when no hooked beads are found. This ensures work is not lost when
a session is interrupted after claiming work.
Previously, gt hook only looked for status=hooked beads, so work that had
been claimed but not completed appeared lost. The fix extends the query to
also include in_progress beads assigned to the agent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>