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>
Enterprise teams can now customize integration branch names to match
their conventions (e.g., username/TICKET-123/feature-name).
- Add integration_branch_template to MergeQueueConfig
- Add --branch CLI override for gt mq integration create
- Support {epic}, {prefix}, {user} template variables
- Validate branch names for git-safe characters
- Store actual branch name in epic metadata at create time
- Read stored branch name in land/status (fallback for old epics)
Also fixes unrelated build error in polecat/manager.go (polecatPath
variable was undefined).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --verbose/-v flag to gt costs command that outputs debug information
when silent failures occur during cost tracking operations:
- wisp list failures in querySessionCostWisps and deleteSessionCostWisps
- bd show failures when querying wisp details
- JSON unmarshal failures when parsing wisp/event data
- payload unmarshal failures when parsing session payloads
This makes debugging cost tracking issues much easier as these error
paths previously continued silently without any indication of failure.
Closes: bd-qv8f9
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sort map keys before iteration in createCostDigestBead for deterministic
output ordering in By Role and By Rig sections (bd-66z6a)
- Batch wisp IDs into single bd show call to fix N+1 query pattern in
querySessionCostWisps (bd-3hqvs)
- Batch wisp deletion into single subprocess call in deleteSessionCostWisps
(bd-i8zab)
Part of: bd-1wmwp
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>
Bare clones don't have remote.origin.fetch set by default, which breaks
worktrees that need to fetch and see origin/* refs. This caused refinery
to fail because origin/main never appeared after fetch.
- Add configureRefspec() to set standard refspec on bare repos
- Call from CloneBare() and CloneBareWithReference()
- Add BareRepoRefspecCheck to doctor for existing rigs
Closes#286
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 EnableMouseMode() and calls it from ConfigureGasTownSession so all
new GT sessions get mouse support. Users can now click panes, scroll with
mouse wheel, and resize by dragging. Hold Shift for terminal text selection.
Closes#33
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>
* 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>
- Remove unused ensureRefinerySession function from start.go
- Remove unused ensureSession and ensureWitness functions from up.go
- Remove unused ensureWitnessSession function from witness.go
- Remove orphaned imports (runtime, session, constants, config, rig, filepath, time)
- Fix indentation error in daemon.go triggerPendingSpawns comment
These functions were added as part of the Codex/OpenCode runtime support
but were never wired up. The existing managers (refinery.Manager.Start,
witness.Manager.Start) already handle session creation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Polecats were creating GitHub PRs instead of using gt done to submit
to the Refinery. Added clear conditional language:
- If repo is steveyegge/beads or steveyegge/gastown: NEVER create PRs
- Polecats use gt done → Refinery merges
- Crew workers push directly to main
- PRs are for external contributors only
This fixes a prompting gap that led to PR #292 being created incorrectly.
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>
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>
Adds a visible "CRITICAL" warning and pre-submission checklist to the
polecat template. Explicitly notes that polecats should NOT manually
close the root issue - the Refinery handles that after merge.
This addresses the intent of PR #287 while avoiding the conflicting
`bd close` instruction that would break the Refinery workflow.
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>
When rig/.beads doesn't exist, fall back to mayor/rig/.beads (tracked
beads architecture) with a warning suggesting 'bd doctor' to fix.
This restores behavior that was inadvertently removed in #290, which
simplified SetupRedirect but removed the fallback path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the hand-rolled contains() function with the standard library
strings.Contains(). Also removes the redundant len(data) > 0 check
since strings.Contains handles empty strings correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The t.Skipf call had a raw newline inside a double-quoted string,
which is invalid Go syntax. Use \n escape sequence instead.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The SessionHookCheck was incorrectly flagging 'gt prime --hook' as invalid,
only accepting 'session-start.sh' wrapper. The --hook flag properly handles
session_id passthrough via stdin JSON, making it a valid alternative.
Changes:
- Update usesSessionStartScript to accept --hook flag
- Add containsFlag helper to prevent false positives (e.g., --hookup)
- Update error messages and fix hints to suggest both options
- Add comprehensive tests including edge cases
Tests cover:
- Bare gt prime (fails)
- gt prime --hook (passes)
- gt prime --hookup (fails - not a valid flag)
- gt prime --verbose --hook (passes - flag order doesn't matter)
- session-start.sh (passes)
- Mixed valid/invalid hooks in same file
- Town-level and rig-level settings
- Add custom types config after bd init in daemon tests
- Replace fixed sleeps with poll-based waiting in tmux tests
- Skip beads integration test for JSONL-only repos
Fixes flaky test failures in parallel execution.
Adds RigBeadsCheck to gt doctor to verify rig identity beads exist.
These beads track rig metadata (git URL, prefix, state) and are created
by gt rig add. The check scans routes.jsonl and verifies each rig
has an identity bead, with --fix to create missing ones.
Recovered from furiosa's uncommitted work after worker interruption.
Co-Authored-By: furiosa <noreply@anthropic.com>
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>
Claude Code can report its pane command as "node", "claude", or a version
number like "2.0.76". Previously only "node" was detected, causing healthy
sessions to be incorrectly identified as zombies and killed during daemon
heartbeat recovery.
This fix detects all three patterns to prevent witness sessions from being
killed every 3 minutes.
Based on michaellady's work in PR #174.
Co-Authored-By: michaellady <michaellady@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The orphan-processes check previously killed any Claude process without
a tmux ancestor, which incorrectly targeted user's personal Claude
sessions running in regular terminals.
Now the check is informational only:
- Changed from FixableCheck to BaseCheck (no auto-fix)
- Returns StatusOK with details listing processes outside tmux
- Message advises user to verify processes are expected
- Removed Fix method and related helpers
The orphan-sessions check remains fixable since it only targets gt-*
sessions that don't match valid Gas Town patterns.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The heartbeat now explicitly calls ensureDeaconRunning() for basic
"is Deacon alive" checks, while Boot handles intelligent triage
(stuck/nudge/interrupt decisions).
Changed ensureDeaconRunning to use deacon.Manager.Start() instead of
duplicating startup logic. This gives daemon the same benefits:
- WaitForShellReady (fixes race condition)
- Claude settings setup
- Theming
- StartupNudge and PropulsionNudge (GUPP)
Heartbeat order:
1. ensureDeaconRunning - restart if dead (via Manager)
2. ensureBootRunning - intelligent triage for stuck states
3. checkDeaconHeartbeat - belt-and-suspenders fallback
4-11. Other checks (witnesses, refineries, polecats, etc.)
This was inadvertently removed when Boot was introduced, which
delegated all Deacon checks to Boot. But Boot's mol doesn't actually
restart Deacon - it just reports. Now responsibilities are clear:
daemon ensures alive, Boot ensures responsive.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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>