Town-level services (Mayor, Deacon) now use hq- prefix instead of gt-:
- hq-mayor (was gt-mayor)
- hq-deacon (was gt-deacon)
This distinguishes town-level sessions from rig-level sessions which
continue to use gt- prefix (gt-gastown-witness, gt-gastown-crew-max, etc).
Changes:
- session.MayorSessionName() returns "hq-mayor"
- session.DeaconSessionName() returns "hq-deacon"
- ParseSessionName() handles both hq- and gt- prefixes
- categorizeSession() handles both prefixes
- categorizeSessions() accepts both prefixes
- Updated all tests and documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Audit of test coverage identifying:
- 10 packages with 0 test coverage (2,452 lines)
- Priority list for new tests (internal/lock is P0)
- 1 flaky test candidate (feed/curator_test.go)
- Test quality analysis and recommendations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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>
When slinging rig-level beads (gt-*, bd-*, etc.), the BEADS_DIR was
unconditionally set to town beads, which could bypass the redirect-based
routing needed for these beads. This caused assignee updates to potentially
fail silently or target the wrong database.
Changes:
- sling.go: Only set BEADS_DIR for town-level (hq-*) beads; rig-level
beads now use redirect from polecat worktree for proper routing
- convoy.go: Add --no-daemon to bd show calls to ensure fresh data
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create internal/agent package with shared State type and StateManager
- StateManager uses Go generics for type-safe load/save operations
- Update witness and refinery to use shared State type alias
- Replace loadState/saveState implementations with StateManager delegation
- Maintains backwards compatibility through re-exported constants
🤖 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>
Create util.ExecWithOutput and util.ExecRun to consolidate repeated
exec.Command patterns across witness/handlers.go and refinery/manager.go.
Changes:
- Add internal/util/exec.go with ExecWithOutput (returns stdout) and
ExecRun (runs command without output)
- Refactor witness/handlers.go to use utility functions (7 call sites)
- Refactor refinery/manager.go, removing unused gitRun/gitOutput methods
- Add comprehensive tests in exec_test.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extracted duplicate bd command execution pattern from mailbox.go and
router.go into a new helper function in bd.go. This reduces code
duplication and provides consistent error handling via the bdError type.
Changes:
- Added internal/mail/bd.go with runBdCommand helper and bdError type
- Refactored 5 functions in mailbox.go to use runBdCommand
- Refactored 5 functions in router.go to use runBdCommand
- Net reduction of 55 lines of code
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- DiscoverRigs() now logs failed rig loads to stderr instead of silently
continuing
- AddRig warnings now output to stderr instead of stdout, matching the
codebase convention for non-fatal warnings
- Added clarifying comment for best-effort git ref update in worktree
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, when gt done was called, it cleared the agent's hook_bead
slot but didn't update the status of the hooked bead itself. This left
handoff beads with status=hooked forever.
Now the hooked bead is closed (status changed from hooked to closed)
before clearing the agent's hook slot.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The TestIntegration test was flaky because it uses the real .beads directory
and the SQLite database could be out of sync with the JSONL file (e.g., after
git pull updates the JSONL but before the database is re-imported).
The fix runs `bd sync --import-only` at the start of the test to ensure
the database is synchronized before running the actual test operations.
Fixes gt-5ww96
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add debugSession helper that logs non-fatal errors when GT_DEBUG_SESSION=1.
Replaced all _ = error patterns with debugSession() calls for better
visibility when diagnosing session startup issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, listFromDir silently ignored all query errors and returned an
empty list with no error if all queries failed. This could hide real problems
like a corrupted beads database or missing bd command.
Now the function tracks whether at least one query succeeded. If all queries
fail, it returns the last error wrapped with context. This enables graceful
degradation (partial results if some queries work) while surfacing complete
failures.
(gt-lm41t)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The --molecule flag was defined but never wired up - the slingMolecule
variable was set by the flag parser but never read by any code path.
Users should use --on instead, which is fully implemented:
gt sling <formula> --on <bead> <target>
The --on flag properly instantiates the formula (cook + wisp + bond)
and applies it to the target bead before slinging.
Keeping --on as the canonical way to apply formulas to beads since it's
actually wired up and working. The --molecule flag can be re-added later
if a different argument order is desired.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The --quality flag (basic|shiny|chrome) referenced mol-polecat-* formulas
that were removed in c47a746 ("Remove obsolete polecat formula files") but
the flag code was left behind, causing errors when used.
Rather than restore the formulas, remove the flag entirely since:
- The default `gt sling <bead> <rig>` is now the standard workflow
- Formula-on-bead via `--on` or `--molecule` covers custom workflows
- The quality-level formulas were intentionally deprecated
Removes:
- --quality/-q flag and help text
- qualityToFormula() function
- Quality Levels section from command documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add isValidBeadsPrefix() to validate prefix format before passing to
exec.Command. Prefixes from config files (detectBeadsPrefixFromConfig)
are now validated to contain only alphanumeric and hyphen characters,
start with a letter, and be max 20 chars.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Verifies all clones have core.hooksPath set to .githooks.
Auto-fixable with 'gt doctor --fix'.
This ensures the pre-push hook is active on all clones,
blocking pushes to invalid branches (no internal PRs).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use regexp.QuoteMeta to treat Query and FromFilter as literal strings
instead of raw regex patterns. This prevents ReDoS attacks from malicious
patterns and provides more intuitive literal string matching for users.
Fixes gt-kwa09
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Audit of test coverage identifying:
- 10 packages with 0 test coverage (2,452 lines)
- Priority list for new tests (internal/lock is P0)
- 1 flaky test candidate (feed/curator_test.go)
- Test quality analysis and recommendations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Avoid template literals with backticks that confuse YAML parsers.
Use array.join() instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --no-daemon to all 17 bd exec calls to bypass daemon socket timing issues
- Set BEADS_DIR in verifyBeadExists() so bd can find beads from any directory
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Gas Town agents must push directly to main, not create PRs.
This adds defense-in-depth:
1. .githooks/pre-push - Blocks pushes to non-main branches locally
2. .github/workflows/block-internal-prs.yml - Auto-closes PRs from
the same repo (forks/contributors can still create PRs)
3. internal/git/git.go - Auto-configures core.hooksPath on clone
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add error suppression for enc.Encode() calls in info.go (errcheck lint)
- Add missing encoding/json import in install_integration_test.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes PR #39 to follow the pattern established in PR #54 - all beads
initialization in done.go should use ResolveBeadsDir to support
.beads/redirect files in worktrees.
* 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>
Sync with mayor/rig fix: Set hook slot in CreateAgentBead and pass
beadID to UpdateAgentState.
Fixes: mi-619
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Previously, BuildStartupCommand, GetRuntimeCommand, and
GetRuntimeCommandWithPrompt would fall back to DefaultRuntimeConfig()
(hardcoded "claude") when rigPath was empty, instead of reading
the town settings for the default_agent.
This meant that `gt config default-agent` had no effect on town-level
agents like the mayor.
Fix: Added findTownRootFromCwd() to detect town root from cwd,
then call ResolveAgentConfig() to read the town's default_agent
setting and custom agents.
Now `gt mayor attach` (and other town-level agents) correctly use
the agent configured in town settings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When no rig argument is provided, now uses GetRole() to detect the
rig from the current directory or GT_ROLE environment variable.
Shows a helpful error message if rig cannot be determined.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The issue: gt crew start --all was not priming crew sessions like
gt crew at does.
Root cause: gt crew at passes "gt prime" as the initial prompt to
BuildCrewStartupCommand(), while gt crew start (via startCrewMember
and runStartCrew) passed an empty string and tried to send gt prime
afterwards via NudgeSession. This created a race condition where the
SessionStart hook would fire and Claude would start responding before
the nudge arrived.
Fix: Pass "gt prime" directly in the startup command for all three
cases: startCrewMember, runStartCrew new session, and runStartCrew
session restart. This makes the behavior consistent with gt crew at.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wisps now live in main .beads/ directory with type=wisp instead
of a separate .beads-wisp/ directory. Updated documentation to
reflect this architectural change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates README.md and docs/reference.md with the new gt config command usage, including:
- All subcommands (agent list, get, set, remove, default-agent)
- Example of setting up a custom agent (claude-glm)
- Note about overriding built-in agents
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>