Commit Graph

2574 Commits

Author SHA1 Message Date
julianknutsen
29e2c6ed9c Fix daemon polecat respawn to pass rigPath for rig agent settings
Daemon's restartPolecatSession was calling BuildPolecatStartupCommand
with empty rigPath, causing polecats to fall back to town-level defaults
instead of honoring rig-specific agent settings.

Now passes rigPath so rig agent settings are honored.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:44:16 -08:00
julianknutsen
454b2f76e7 Fix witness to pass rigPath for rig agent settings
Witness was calling BuildAgentStartupCommand with empty rigPath,
causing it to fall back to town-level defaults instead of honoring
rig-specific agent settings (like RigSettings.Agent).

Now passes m.rig.Path so rig agent settings are honored, consistent
with how refinery already passes the rig path.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:40:34 -08:00
julianknutsen
21c1bbc118 Fix Claude settings tests for correct mayor settings location
Tests were creating mayor settings at townRoot/.claude/ but the check
now correctly identifies that location as wrong (should be mayor/.claude/).

Updated tests to use mayor/.claude/settings.json which is the correct
location that doesn't pollute child workspaces via directory traversal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:37:23 -08:00
julianknutsen
ea8bef2029 refactor: unify agent startup with Manager pattern
- Create mayor.Manager for mayor lifecycle (Start/Stop/IsRunning/Status)
- Create deacon.Manager for deacon lifecycle with respawn loop
- Move session.Manager to polecat.SessionManager (clearer naming)
- Add zombie session detection for mayor/deacon (kills tmux if Claude dead)
- Remove duplicate session startup code from up.go, start.go, mayor.go
- Rename sessMgr -> polecatMgr for consistency
- Make witness/refinery SessionName() public for status display

All agent types now follow the same Manager pattern:
  mgr := agent.NewManager(...)
  mgr.Start(...)
  mgr.Stop()
  mgr.IsRunning()
  mgr.Status()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:32:35 -08:00
julianknutsen
432d14d9df Install Claude settings during rig and HQ creation
Creates settings.json automatically during initial setup, so Claude
settings are available immediately on launch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:44:05 -08:00
julianknutsen
b7b8e141b1 Move mayor files into mayor/ subdirectory
Prevents mayor-specific files (CLAUDE.md, hooks) from polluting child
agent workspaces. Child agents inherit the parent's working directory,
so keeping mayor files in a dedicated subdirectory ensures they don't
interfere with agent operations.

Includes:
- MayorDir constant in templates for consistent path handling
- Updated hooks.go, prime.go, role.go to use mayor/ paths
- Documentation updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:44:05 -08:00
julianknutsen
72544cc06d Unify agent startup with Manager pattern
Refactors all agent startup paths (witness, refinery, crew, polecat) to use
a consistent Manager interface with Start(), Stop(), IsRunning(), and
SessionName() methods.

Includes:
- Witness manager with GUPP propulsion nudge for startup
- Refinery manager for engineer sessions
- Crew manager for worker agents
- Session/polecat manager updates
- claude_settings_check doctor check for settings validation
- Settings management consolidated from rig/manager.go
- Settings location moved outside source repos to prevent conflicts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:44:04 -08:00
julianknutsen
81a7d04239 Add sparse checkout to exclude Claude context files from source repos
Excludes all Claude Code context files to prevent source repo instructions
from interfering with Gas Town agent configuration:
- .claude/       : settings, rules, agents, commands
- CLAUDE.md      : primary context file
- CLAUDE.local.md: personal context file
- .mcp.json      : MCP server configuration

Legacy configurations (only excluding .claude/) are detected and upgraded
by gt doctor --fix.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 21:01:07 -08:00
gastown/crew/joe
fc4b9de02c fix: use tmux for agent liveness in daemon checks (gt-zecmc)
Complete the "discover, don't track" refactoring:

- checkGUPPViolations: use tmux.IsClaudeRunning() instead of agent_state
- checkOrphanedWork: derive dead agents from tmux, not agent_state=dead
- assessStaleness: rely on HasActiveSession (tmux), not agent_state

Non-observable states (stuck, awaiting-gate) are still respected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:50:01 -08:00
capable
9729e05f86 feat(rig): add operational state to gt rig status
Add Status line showing operational state (OPERATIONAL/PARKED/DOCKED)
with source indication (local/global - synced/default).

The state is looked up using the property layer system:
1. Wisp layer (local/ephemeral): .beads-wisp/config/<rig>.json
2. Rig bead labels (global/synced): status:parked or status:docked
3. Default: OPERATIONAL

Example output:
  gastown
    Status: PARKED (local)
    Path: /Users/stevey/gt/gastown
    ...

Closes: gt-5l7h4

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:43:51 -08:00
nux
3f920048cb feat(rig): add dock/undock commands for Level 2 rig control (gt-9gm9n)
Implement gt rig dock <rig> and gt rig undock <rig> commands for
global/persistent rig control:

- dock: stops witness/refinery, sets status:docked label on rig bead
- undock: removes docked label, allows daemon to restart agents

This is Level 2 (global/persistent) control:
- Uses rig identity bead labels (synced via git)
- Affects all clones of the rig
- Persists until explicitly undocked

Also includes cherry-picked rig identity bead infrastructure:
- RigFields struct for rig metadata
- CreateRigBead and RigBeadID helpers
- Auto-create rig bead for legacy rigs on first dock

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:43:27 -08:00
rictus
d00e73f110 feat(daemon): respect rig operational state for auto-start
Update daemon to check rig config before auto-starting agents:
- Check wisp config "status" - skip if parked or docked
- Check "auto_restart" config - skip if blocked or false
- Log skip reason for visibility

Affects ensureWitnessRunning, ensureRefineryRunning,
restartPolecatSession, and lifecycle restartSession.

(gt-68c46)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:43:00 -08:00
gastown/crew/joe
87169a3fc7 fix: complete removal of agent_state observable tracking (gt-zecmc)
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>
2026-01-06 20:42:23 -08:00
furiosa
6e84489ca3 feat(rig): add park/unpark commands for Level 1 rig control
Implement gt rig park <rig> and gt rig unpark <rig> commands:
- park: stops witness/refinery, sets status=parked in wisp layer
- unpark: clears parked status, allows daemon to restart agents

This is Level 1 (local/ephemeral) control - affects only this town
and disappears on wisp cleanup. Exports IsRigParked() for daemon use.

(gt-vxv0u)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:41:01 -08:00
dementus
29aed4b42f feat(rig): add gt rig config commands (gt-hhmkq)
Implements config viewing and manipulation commands for rig configuration
across property layers.

Commands:
- gt rig config show <rig>           # Show effective config
- gt rig config show <rig> --layers  # Show source of each value
- gt rig config set <rig> <key> <value>          # Set in wisp layer
- gt rig config set <rig> <key> <value> --global # Set in bead layer
- gt rig config set <rig> <key> --block          # Block inheritance
- gt rig config unset <rig> <key>                # Remove from wisp

Includes cherry-picked dependencies:
- Property layer lookup (cb927a73, gt-emh1c)
- Rig identity bead schema for bead layer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:40:40 -08:00
slit
805ac7c17a feat(rig): implement property layer lookup (gt-emh1c)
Implements unified config lookup across all layers:
1. Wisp layer (transient, town-local)
2. Rig identity bead labels
3. Town defaults
4. System defaults (compiled-in)

Two lookup modes:
- Override: First non-nil value wins (default)
- Stacking: Integer values sum (for priority_adjustment)

API on Rig:
- GetConfig(key) interface{}
- GetIntConfig(key) int (stacking for priority_adjustment)
- GetBoolConfig(key) bool
- GetStringConfig(key) string
- GetConfigWithSource(key) (value, source)

Includes cherry-picked dependencies:
- Wisp config storage layer (nux, gt-3w685)
- Rig identity bead schema (furiosa, gt-zmznh)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:40:14 -08:00
furiosa
ec53dfbb40 feat(rig): add rig identity bead schema and creation (gt-zmznh)
- Add RigFields struct, CreateRigBead, RigBeadID helpers to beads package
- Modify gt rig add to create rig identity bead after rig creation
- Schema: id=<prefix>-rig-<name>, type=rig, with repo/prefix/state fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:39:41 -08:00
gastown/crew/joe
1f44482ad0 fix: remove observable states from agent_state (discover, don't track)
The agent_state field was recording observable state like "running",
"dead", "idle" which violated the "Discover, Don't Track" principle.
This caused stale state bugs where agents were marked "dead" in beads
but actually running in tmux.

Changes:
- Remove daemon's checkStaleAgents() which marked agents "dead"
- Simplify ensureXxxRunning() to use tmux.IsClaudeRunning() directly
- Remove reportAgentState() calls from gt prime and gt handoff
- Add SetHookBead/ClearHookBead helpers that don't update agent_state
- Use ClearHookBead in gt done and gt unsling
- Simplify gt status to derive state from tmux, not bead

Non-observable states (stuck, awaiting-gate, muted, paused) are still
set because they represent intentional agent decisions that can't be
discovered from tmux state.

Fixes: gt-zecmc

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 20:32:02 -08:00
gastown/crew/jack
950e35317e feat(status): add compact one-line-per-worker output as default
- 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>
2026-01-06 20:12:39 -08:00
gastown/crew/joe
6dbb841e22 fix(daemon): nudge agents on state divergence instead of silent accept
When the daemon detects that an agent bead state doesn't match tmux
(e.g., bead says stopped but Claude is running), it now:

1. Logs the divergence clearly with STATE DIVERGENCE prefix
2. Nudges the agent with an actionable command to fix its state
3. Still skips the restart (safety - don't kill healthy sessions)

This prevents silent state drift where bead state diverges from reality.
Applied to: Deacon, Witness, Refinery ensure functions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 19:23:52 -08:00
jv
d89aae5b5c docs: mention agent config and --agent in onboarding 2026-01-06 19:13:14 -08:00
jv
11e3e85e9d docs: document --agent overrides 2026-01-06 19:13:14 -08:00
jv
99aae0bf02 fix: use canonical hq role bead IDs 2026-01-06 19:13:14 -08:00
jv
22693c1dcc feat: runtime-aware tmux agent checks 2026-01-06 19:13:14 -08:00
jv
02ca9e43fa fix: honor rig agent when starting witness/refinery 2026-01-06 19:12:55 -08:00
jv
6afd85df4b feat: add --agent overrides to start/attach 2026-01-06 19:11:58 -08:00
jv
3b9ca71fc4 feat: add --agent override for sling 2026-01-06 19:11:58 -08:00
Subhrajit Makur
93b19a7e72 feat: add watch mode to gt status (#8) (#11) (#231)
* feat: add watch mode to gt status

- Add --watch/-w flag for continuous status refresh
- Add --interval/-n flag to set refresh interval (default 2s)
- Clears screen and shows timestamp on each refresh
- Graceful Ctrl+C handling to stop watch mode
- Works with existing --fast and --json flags

* fix(status): validate watch interval to prevent panic on zero/negative values

* fix(status): harden watch mode with signal cleanup, TTY detection, and tests

- Add defer signal.Stop() to prevent signal handler leak
- Reject --json + --watch combination (produces invalid output)
- Add TTY detection for ANSI escapes (safe when piped)
- Use style.Dim for header when in TTY mode
- Fix duplicate '(default 2)' in flag help
- Add tests for interval validation and flag conflicts
2026-01-06 19:10:43 -08:00
gastown/crew/joe
c2451b85e7 Merge origin/main into fix/205-address-claude-startup-issues
Resolved conflict in internal/witness/manager.go:
- Kept session import (used by PR code)
- Kept PR's more accurate comment for PID check
- Removed duplicate sessionName method introduced by merge
2026-01-06 19:04:29 -08:00
nux
ae88c12e07 feat(wisp): add config storage layer for transient/local settings
Implement wisp-based config storage at .beads-wisp/config/<rig>.json
for local-only settings that are never synced via git.

API:
- Get(key) - returns value or nil
- Set(key, value) - stores value
- Block(key) - marks key as blocked (NullValue equivalent)
- Unset(key) - removes from values and blocked
- IsBlocked(key) - checks if blocked

(gt-3w685)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 19:01:34 -08:00
gastown/crew/joe
e7a8e0a3db bead: ZFC convoy auto-close on bd close (gt-3qw5s) 2026-01-06 18:53:59 -08:00
gastown/crew/joe
56742d95da docs: Add property-layers.md implementation guide
Multi-level configuration for Gas Town:
- gt rig park/unpark (local, ephemeral)
- gt rig dock/undock (global, persistent)
- Property layer lookup implementation

Related: gt-ih6xy

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 17:39:03 -08:00
furiosa
60e7471cea fix(witness): Kill tmux session on Stop()
The witness manager's Stop() method was only updating runtime JSON state
without killing the tmux session, causing 'gt rig shutdown' to leave
witness sessions running.

Added sessionName() method and tmux kill-session logic to match the
refinery's existing implementation.

Fixes: bd-gxaf

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 14:04:52 -08:00
gastown/crew/jack
7edd75021b fix: revert heretical gt witness process command, update formula for ZFC (gt-h3gzj)
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.
2026-01-06 13:33:20 -08:00
gastown/crew/max
a787d60add fix(crew): add dry-run support and error handling to crew stop (gt-kjcx4)
Fixed two issues in `gt crew stop <name>`:

1. --dry-run flag now works for individual crew stops (previously only
   worked with --all)

2. HasSession errors are now properly handled instead of being ignored,
   which could cause "No session found" messages even when sessions exist

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:25:10 -08:00
gastown/crew/jack
a3bccc881b fix: add gt witness process command to invoke polecat cleanup handlers (gt-h3gzj)
The Witness handlers (HandlePolecatDone, HandleMerged, etc.) existed in Go
code but were never called - there was no CLI command to invoke them.

This caused polecats to remain in 'done' state after MR merge because
POLECAT_DONE messages were never processed.

Changes:
- Add `gt witness process <rig>` command to process Witness mail
- Fix --wisp flag to --ephemeral in cleanup wisp creation
- Command processes POLECAT_DONE, MERGED, HELP, SWARM_START messages
- Auto-nukes clean polecats, creates cleanup wisps for dirty ones

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:22:10 -08:00
gastown/crew/gus
74409dc32b feat(deacon): add stale hooked bead cleanup (gt-2yls3)
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>
2026-01-06 13:20:45 -08:00
gastown/crew/george
ac63b10aa8 feat(formula): update mol-town-shutdown to v3 with full cleanup (gt-ux23f)
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>
2026-01-06 13:19:00 -08:00
gastown/crew/george
c306879a31 fix(refinery): merge local branches instead of fetching from origin (gt-cio03)
Phase 2 of Heresy Correction: Local-Only Polecat Branches

Changes:
- Replace FetchBranch("origin", branch) with BranchExists() check
- Use local branch directly for CheckConflicts() and MergeNoFF()
- Remove "origin/" prefix from branch references

The Refinery worktree shares .repo.git with polecat worktrees, so
branches created by polecats are already visible locally without
needing to fetch from origin.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:14:58 -08:00
gastown/crew/max
ac4649ba7d docs(polecat): remove push instructions for local-only branches (gt-cqw0n)
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>
2026-01-06 13:11:54 -08:00
gastown/crew/gus
63af29284b feat(witness): delay polecat cleanup until MR merges (gt-12hwb)
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>
2026-01-06 13:11:43 -08:00
gastown/crew/jack
b79e4a7c3b fix: remove BranchPushedToRemote checks from gt done and mq submit (gt-dymy5)
Phase 1 of local-only polecat branches. Removes push verification checks
since polecats will no longer push branches to remote.

- done.go: Remove push check, keep existing CommitsAhead validation
- mq_submit.go: Remove push check entirely

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:09:32 -08:00
markov-kernel
6fe25c757c fix(refinery): Send MERGE_FAILED to Witness when merge is rejected
When the Refinery detects a build error or test failure and refuses
to merge, the polecat was never notified. This fixes the notification
pipeline by:

1. Adding MERGE_FAILED protocol support to Witness:
   - PatternMergeFailed regex pattern
   - ProtoMergeFailed protocol type constant
   - MergeFailedPayload struct with all failure details
   - ParseMergeFailed parser function
   - ClassifyMessage case for MERGE_FAILED

2. Adding HandleMergeFailed handler to Witness:
   - Parses the failure notification
   - Sends HIGH priority mail to polecat with fix instructions
   - Includes branch, issue, failure type, and error details

3. Adding mail notification in Refinery's handleFailureFromQueue:
   - Creates mail.Router for sending protocol messages
   - Sends MERGE_FAILED to Witness when merge fails
   - Includes failure type (build/tests/conflict) and error

4. Adding comprehensive unit tests:
   - TestParseMergeFailed for full body parsing
   - TestParseMergeFailed_MinimalBody for minimal body
   - TestParseMergeFailed_InvalidSubject for error handling
   - ClassifyMessage test cases for MERGE_FAILED

Fixes #114

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:02:46 -08:00
mayor
9cb14cc41a fix(sling): resolve rig path for cross-rig bead hooking
gt sling failed when hooking rig-level beads from town root because
bd update doesn't support cross-database routing like bd show does.

The fix adds a ResolveHookDir helper that:
1. Extracts the prefix from bead ID (e.g., "ap-xxx" → "ap-")
2. Looks up the rig path from routes.jsonl
3. Falls back to townRoot if prefix not found

Also removes the BEADS_DIR environment override which was preventing
routing from working correctly.

Fixes #148
2026-01-06 13:00:46 -08:00
Martin Emde
201ef3a9c8 Replace gt rigs with gt rig list in templates and docs (#217)
The command was renamed from `gt rigs` to `gt rig` with subcommands.
This updates all references to use `gt rig list` for listing rigs.
2026-01-06 12:59:49 -08:00
Martin Emde
9e416e9ff5 Fix handoff loses claude code environment variables (#216)
buildRestartCommand() now propagates Claude-related env vars when
respawning sessions via tmux. Fresh shells don't inherit parent env,
so CLAUDE_CODE_USE_BEDROCK, ANTHROPIC_API_KEY, AWS_*, etc. were lost.
This caused any tmux respawn to result in a non-functional claude.

Adds claudeEnvVars list and includes them in the export command when
building the restart command.
2026-01-06 12:59:45 -08:00
Dave Williams
83c47df980 📝 (README.md): rewrite documentation with comprehensive guides, archi… (#226)
* 📝 (README.md): rewrite documentation with comprehensive guides, architecture diagrams, and detailed workflows
The README has been completely overhauled to provide a more structured and detailed explanation of the Gas Town system. It now includes architecture diagrams, in-depth descriptions of core concepts, step-by-step installation and usage guides, and troubleshooting tips to improve the developer onboarding experience.

* 📝 (README.md): improve formatting, alignment, and spacing

The tables are realigned to improve readability in the raw view, and missing newlines are added before code blocks and after section headers to ensure proper rendering and visual separation.
2026-01-06 12:59:44 -08:00
Subhrajit Makur
7fe505d673 fix: create mayor/daemon.json during gt start and gt doctor --fix (#225)
* fix: create mayor/daemon.json during gt start and gt doctor --fix (#5)

- Add DaemonPatrolConfig type with heartbeat and patrol settings
- Add Load/Save/Ensure functions for daemon patrol config
- Create daemon.json in gt start (non-fatal if fails)
- Make PatrolHooksWiredCheck fixable with Fix() method
- Add comprehensive tests for both config and doctor checks

This fixes the issue where gt doctor expects mayor/daemon.json to exist
but it was never created by gt start or any other command.

* refactor: use constants.DirMayor instead of hardcoded string
2026-01-06 12:59:41 -08:00
Julian Knutsen
9d7dcde1e2 feat: Unified beads redirect for tracked and local beads (#222)
* feat: Beads redirect architecture for tracked and local beads

This change implements proper redirect handling so that all rig agents
(Witness, Refinery, Crew, Polecats) can work with both:
- Tracked beads: .beads/ checked into git at mayor/rig/.beads
- Local beads: .beads/ created at rig root during gt rig add

Key changes:

1. SetupRedirect now handles tracked beads by skipping redirect chains.
   The bd CLI doesn't support chains (A→B→C), so worktrees redirect
   directly to the final destination (mayor/rig/.beads for tracked).

2. ResolveBeadsDir is now used consistently in polecat and refinery
   managers instead of hardcoded mayor/rig paths.

3. Rig-level agents (witness, refinery) now use rig beads with rig
   prefix instead of town beads. This follows the architecture where
   town beads are only for Mayor/Deacon.

4. prime.go simplified to always use ../../.beads for crew redirects,
   letting rig-level redirect handle tracked vs local routing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(doctor): Add beads-redirect check for tracked beads

When a repo has .beads/ tracked in git (at mayor/rig/.beads), the rig root
needs a redirect file pointing to that location. This check:

- Detects missing rig-level redirect for tracked beads
- Verifies redirect points to correct location (mayor/rig/.beads)
- Auto-fixes with 'gt doctor --fix'

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Handle fileLock.Unlock error in daemon

Wrap fileLock.Unlock() return value to satisfy errcheck linter.

🤖 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>
2026-01-06 12:59:37 -08:00
Martin Emde
16fb45bb2a Add .repo.git/ to gitignore during rig setup (#219)
This prevents .repo.git/ directories from showing up as untracked files
in town git status.

Changes:
- manager.go: Add .repo.git/ to rig .gitignore during setup
2026-01-06 12:59:33 -08:00