Commit Graph

76 Commits

Author SHA1 Message Date
gastown/crew/joe
598a39e708 fix: prevent inherited BEADS_DIR from causing prefix mismatch (#321)
- Fix beads.run() to always explicitly set BEADS_DIR based on the working
  directory or explicit override
- This prevents inherited environment variables (e.g., from mayor session
  with BEADS_DIR=/home/erik/gt/.beads) from causing prefix mismatch errors
  when creating agent beads for rigs
- Update polecat manager to use NewWithBeadsDir for explicitness
- Add comprehensive test coverage for BEADS_DIR routing and validation
- Add SessionLister interface for deterministic orphan session testing

Root cause: When BEADS_DIR was set in the parent environment, all bd
commands used the town database (hq- prefix) instead of the rig database
(gt- prefix), causing "prefix mismatch: database uses 'hq' but you
specified 'gt'" errors during polecat spawn.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 18:33:34 -08:00
Steve Brown
3246c7c6b7 fix(beads): add CreateOrReopenAgentBead for polecat re-spawn (#333)
When a polecat is nuked and re-spawned with the same name, CreateAgentBead
fails with a UNIQUE constraint error because the old agent bead exists as
a tombstone.

This adds CreateOrReopenAgentBead that:
1. First tries to create the agent bead normally
2. If UNIQUE constraint fails, reopens the existing bead and updates fields

Updated both spawn paths in polecat manager to use the new function.

Fixes #332

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-10 22:56:37 -08:00
tanevanwifferen
d13922523a fix(worktree): use rig's configured default branch for polecat/dog worktrees (#325)
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>
2026-01-10 16:29:54 -08:00
mayor
db353c247b feat: implement priming subsystem improvements
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>
2026-01-10 01:07:01 -08:00
gastown/crew/george
b92e46474a fix(polecat): remove pending.json tracking anti-pattern (ZFC)
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>
2026-01-09 22:11:14 -08:00
julianknutsen
e999ceb1c1 refactor: consolidate agent env vars into config.AgentEnv
Create centralized AgentEnv function as single source of truth for all
agent environment variables. All agents now consistently receive:
- GT_ROLE, BD_ACTOR, GIT_AUTHOR_NAME (role identity)
- GT_ROOT, BEADS_DIR (workspace paths)
- GT_RIG, GT_POLECAT/GT_CREW (rig-specific identity)
- BEADS_AGENT_NAME, BEADS_NO_DAEMON (beads config)
- CLAUDE_CONFIG_DIR (optional account selection)

Remove RoleEnvVars in favor of AgentEnvSimple wrapper.
Remove IncludeBeadsEnv flag - beads env vars always included.
Update all manager and cmd call sites to use AgentEnv.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 21:52:30 -08:00
julianknutsen
1d88a73eaa fix: use ResolveBeadsDir for polecat BEADS_DIR
Previously, polecat startup used hardcoded paths for BEADS_DIR that
didn't follow redirects for repos with tracked beads. This meant
polecats working in worktrees (where .beads/redirect points to the
actual beads location) would use the wrong beads directory.

Fixed locations:
- daemon.go: polecat startup now uses ResolveBeadsDir
- polecat/session_manager.go: session startup now uses ResolveBeadsDir

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 21:52:09 -08:00
furiosa
7367aa7572 docs: add gt nudge guidance to mayor template (hq-6h9w4o)
- Add Coordination section with gt nudge command
- Clarify line 180: routine nudging is Witness job, Mayor can nudge stuck refinery/witness
- Add warning to NEVER use tmux send-keys (drops Enter key)
- Includes liftoff test timestamp in manager.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 14:34:44 -08:00
jack
afff85cdff fix(tmux): use NewSessionWithCommand to avoid send-keys race condition
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>
2026-01-08 23:35:31 -08:00
gastown/crew/max
9b2f4a7652 feat(polecat): add repo path to worktrees for LLM ergonomics (GH#283)
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>
2026-01-08 23:16:10 -08:00
george
65c3e90374 feat: Add Codex and OpenCode runtime backend support (#281)
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>
2026-01-08 22:56:37 -08:00
dennis
e124402b7b fix: crew start rig inference + refactor overlay to shared utility
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>
2026-01-08 22:40:23 -08:00
Steve Yegge
705a7c2137 Merge pull request #278 from EscapeVelocityOperations/main
feat: add .runtime/overlay/ support for polecat/crew worktrees
2026-01-08 22:37:29 -08:00
Ben Kraus
38adfa4d8b codex 2026-01-08 12:36:54 -05:00
cstar
03b0f7ff52 feat: add .runtime/overlay/ support for polecat/crew worktrees
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>
2026-01-08 14:25:02 +01:00
joshuavial
45634059dd Ignore .claude dirs when listing polecats 2026-01-08 22:10:39 +13:00
Julian Knutsen
28a9de64d5 fix(tmux): wait for shell ready before sending keys (#264)
Add WaitForShellReady call before SendKeys in all agent managers
(deacon, mayor, witness, refinery). This prevents intermittent
"can't find pane" errors that occur when the tmux session is
created but the shell isn't ready to receive input yet.

The issue manifests under load (e.g., during `gt up` when multiple
agents start in sequence) where the 200ms delay in SendKeysDelayed
isn't sufficient for the pane to be fully initialized.

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:49:25 -08:00
Julian Knutsen
ffa8dd56cb test(polecat): skip beads-unavailable test when bd is installed (#244)
TestGetReturnsWorkingWithoutBeads assumes bd is not available and
expects state to default to StateWorking. When bd is installed, it
actually queries beads and returns the real state, causing the test
to fail.

Skip the test when bd is detected to avoid environment-dependent
failures.

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 20:41:34 -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
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
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
mayor
c073125b3b Merge remote-tracking branch 'origin/polecat/blackfinger-mk0vu0da' 2026-01-05 19:38:53 -08:00
nux
ca71f9b8de fix: Polecat lifecycle cleanup - stale worktrees and git tracking
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>
2026-01-05 00:23:34 -08:00
blackfinger
904a773ade refactor: Add CleanupStatus type to replace raw strings (gt-77gq7)
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>
2026-01-05 00:19:00 -08:00
gastown/crew/george
bef5a10250 fix: repair worktree starts from origin/<default-branch>
When repairing a stale polecat worktree, start from origin/<default-branch>
instead of the bare repo's HEAD. This ensures repaired polecats have the
latest fetched commits rather than potentially stale code.

- Add WorktreeAddFromRef to git package for creating worktrees from a ref
- RepairWorktreeWithOptions now uses origin/<default-branch> as start point
- Respects rig's configured default branch (main, master, etc.)

Based on PR #112 by markov-kernel. Test changes from that PR can be
submitted separately.

Closes #101

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

Co-Authored-By: markov-kernel <markov-kernel@users.noreply.github.com>
2026-01-04 14:46:36 -08:00
prime
af95b7b7f4 Remove StateIdle and idle polecat concept
The transient polecat model says: "Polecats exist only while working."
This removes the deprecated StateIdle and updates the codebase:

- Remove StateIdle from polecat/types.go (keep StateActive for legacy data)
- Update manager.go: Get() returns StateDone (not StateIdle) when no work
- Update manager.go: Add/Recreate return StateWorking (not StateIdle)
- Remove zombie scan logic from deacon.go (no idle polecats to scan for)
- Update tests to reflect new behavior

The correct lifecycle is now:
- Spawn: polecat created with work (StateWorking)
- Work: sessions cycle, sandbox persists
- Done: polecat signals completion (StateDone)
- Nuke: Witness destroys sandbox

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 14:41:28 -08:00
dinki
871410f157 refactor: Rename RecreateWithOptions to RepairWorktreeWithOptions
Clarify that this operation is for stale state recovery, not normal recycling:

- Recreate → RepairWorktree
- RecreateWithOptions → RepairWorktreeWithOptions
- Updated comments to explain this handles reconciliation when AllocateName
  returns a name that already exists (stale state needing repair)
- Updated polecat_spawn.go output: Recreating → Repairing stale
- Updated gc command help text for consistency

The function is useful for atomic hook_bead setting during repair, so kept
rather than replacing with Remove + Add.

Fixes gt-l0lok

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 14:28:40 -08:00
corpus
b732eb075b Remove gt polecat done/reset/finish/sleep commands (idle producers)
These commands transitioned polecats to idle state, violating the transient
model. From PRIMING.md: "Polecats exist only while working. One task, then nuked."

Removed:
- gt polecat done - marked polecat as done and returned to idle
- gt polecat reset - force reset polecat to idle state
- gt polecat finish - alias for done
- gt polecat sleep - deprecated transition to done state
- gt polecat wake - deprecated transition to working state
- Manager.Finish() method
- Manager.Reset() method
- Manager.Wake() method
- Manager.Sleep() method

The correct model is: polecats use 'gt done' which signals Witness for nuke.
There is no "return to idle" - only death.

(gt-32d4a)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 14:27:54 -08:00
scrotus
4de5a96400 refactor: use hq- prefix for role bead references
Migrate all role bead references from gt-*-role to hq-*-role using
beads.RoleBeadIDTown() function. Role beads are stored in town beads
(~/gt/.beads/) with the hq- prefix.

Changes:
- internal/cmd/prime.go: Use RoleBeadIDTown() for all roles
- internal/doctor/agent_beads_check.go: Use RoleBeadIDTown() for rig agents
- internal/polecat/manager.go: Use RoleBeadIDTown("polecat")
- internal/cmd/crew_add.go: Use RoleBeadIDTown("crew")
- internal/beads/beads.go: Update comments to document hq- convention
- Templates: Update bd show gt-deacon to bd show hq-deacon

Note: Tmux session names remain as gt-* (runtime identifiers).
Bead IDs use hq-* for town-level agents (persistent storage).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 13:17:39 -08:00
Chris Sloane
1733c6dbae fix: use mayor/rig path for beads to prevent prefix mismatch (#38)
When creating agent beads for polecats or crew workers, the code was
using the rig root path (e.g., ~/gt/infra-dashboard/) instead of the
mayor/rig path where the actual beads database lives.

The rig root .beads/ directory only contains config.yaml with no
database. When bd runs from there, it walks up the directory tree
and finds the town-level beads database (with 'gm' prefix) instead
of the rig's database (with the rig's prefix like 'id'). This causes
prefix mismatch errors:

  Error: prefix mismatch: database uses 'gm' but you specified 'id'

The routes.jsonl file maps rig prefixes to <rig>/mayor/rig, so the
code should always use that path for beads operations.

Changes:
- polecat/manager.go: Always use mayor/rig path, remove fallback logic
- cmd/crew_add.go: Use mayor/rig path instead of rig root

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:58:53 -08:00
jack
29058f321c refactor(commands): provision slash commands at town-level only (gt-7x274)
- gt install now creates ~/gt/.claude/commands/ with all commands
- Removed per-workspace provisioning from crew/polecat managers
- Updated bd doctor to check town-level instead of per-workspace
- All agents inherit via Claude directory traversal

This eliminates duplicate /handoff skills in the picker.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 15:49:53 -08:00
slit
d4eed2dcf2 feat(crew): Provision .claude/commands/ for crew and polecat workspaces (gt-jhr85)
When adding a crew member with 'gt crew add' or spawning a polecat,
provision the .claude/commands/ directory with standard slash commands
like /handoff. This ensures all agents have Gas Town utilities even if
the source repo does not have them tracked.

Changes:
- Add embedded commands templates (internal/templates/commands/)
- Add ProvisionCommands() to templates package
- Call ProvisionCommands from crew and polecat managers
- Add gt doctor commands-provisioned check with --fix support
2026-01-02 17:28:40 -08:00
kustrun
b4a6f599ac fix(beads): Use conditional routing based on source repo beads location
Route to the correct beads location based on whether the source repo
has .beads/ tracked in git:
- If source has .beads/ tracked: route to mayor/rig/.beads
- Otherwise: route to rig root .beads/ (created by initBeads)

Updates both route registration in rig.go and polecat manager's
NewManager/setupSharedBeads to use consistent conditional logic.
2026-01-02 22:44:58 +01:00
gastown/polecats/furiosa
e159489edb fix(sling): Set hook_bead atomically at polecat spawn time (gt-h46pk)
When slinging work to a rig (auto-spawning a polecat), the hook_bead
is now set atomically during agent bead creation rather than in a
separate updateAgentHookBead call after spawn.

This fixes cross-beads routing issues when town beads (hq-*) are slung
to rig polecats (gt-* agent beads). By setting hook_bead at creation
time within the polecat manager context, the correct beads routing is
used.

Changes:
- Add AddOptions struct with HookBead field to polecat.Manager
- Add AddWithOptions() and RecreateWithOptions() functions
- Pass HookBead through SlingSpawnOptions in cmd/polecat_spawn.go
- Pass beadID as HookBead in cmd/sling.go for rig target spawns

Note: updateAgentHookBead() is kept for non-spawn targets (existing
agents) and formula-on-bead mode (updates hook to wisp root after
creation).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 18:50:32 -08:00
Steve Yegge
05b1f30381 Fix agent bead prefix mismatch for rigs with custom prefixes (bd-otyh)
When spawning polecats in rigs with custom prefixes (e.g., beads uses bd-
instead of gt-), agent beads were being created with hardcoded gt- prefix,
causing warnings like issue ID gt-beads-polecat-obsidian does not match
configured prefix bd.

Changes:
- polecat/manager.go: agentBeadID() now looks up the rigs configured prefix
  from routes.jsonl via beads.GetPrefixForRig()
- prime.go: getAgentBeadID() now uses prefix lookup for rig-level agents
  (witness, refinery, polecat, crew)

Town-level agents (mayor, deacon) continue to use gt- prefix as expected.
2025-12-30 16:56:46 -08:00
Steve Yegge
9ebc733623 fix: stop writing Gas Town context to polecat CLAUDE.md
Same fix as crew: polecat manager was overwriting project CLAUDE.md with
Gas Town polecat context. Gas Town context is now injected ephemerally via
SessionStart hook (gt prime) only.

Removed installCLAUDETemplate function and associated tests.
2025-12-30 12:01:27 -08:00
Steve Yegge
be979c66a2 feat: Use base36 encoding for shorter polecat branch names 2025-12-30 10:20:51 -08:00
Steve Yegge
c92b11d1bd feat: Standardize agent bead naming to prefix-rig-role-name (gt-zvte2)
Implements canonical naming convention for agent bead IDs:
- Town-level: gt-mayor, gt-deacon (unchanged)
- Rig-level: gt-<rig>-witness, gt-<rig>-refinery (was gt-witness-<rig>)
- Named: gt-<rig>-crew-<name>, gt-<rig>-polecat-<name> (was gt-crew-<rig>-<name>)

Changes:
- Added AgentBeadID helper functions to internal/beads/beads.go
- Updated all ID generation call sites to use helpers
- Fixed session parsing in theme.go, statusline.go, agents.go
- Updated doctor check and fix to use canonical format
- Updated tests for new format

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 14:54:37 -08:00
Steve Yegge
f2c76304e9 fix: Agent beads now reference shared role beads
crew_add.go: Use gt-crew-role instead of per-instance role bead
polecat/manager.go: Add RoleBead field pointing to gt-polecat-role

Per agent-as-bead design, role beads are shared class definitions.
Each agent bead references its role via the role_bead field/slot.

Fixes gt-ne9he

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 13:42:37 -08:00
Steve Yegge
2f354b1ef6 Enhance gt status with tree-style role hierarchy view (gt-um4iu)
- Use tree characters (├── └── │) for hierarchical display
- Group agents by role type (Witness, Refinery, Crew, Polecats)
- Add role icons (🎩 Mayor, 🔔 Deacon, 👁 Witness, 🏭 Refinery, 👷 Crew, 😺 Polecats)
- Show pinned work inline with truncation
- Fix unused import in polecat/manager.go

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 19:36:15 -08:00
Steve Yegge
d72e86493e Merge morsov: AgentIdentity, session helpers 2025-12-28 18:45:14 -08:00
Steve Yegge
e3ea9c2855 ZFC #10: Polecat self-reports cleanup status
Instead of Go code checking git state to decide if polecat removal is safe,
the polecat now self-reports its cleanup_status via its agent bead.

Changes:
- Add CleanupStatus field to AgentFields struct
- Update FormatAgentDescription and ParseAgentFields for cleanup_status
- Add UpdateAgentCleanupStatus function to beads package
- Update gt done to compute and report git cleanup status
- Update RemoveWithOptions to read cleanup_status from agent bead first,
  falling back to git check for backward compatibility

Valid cleanup_status values:
- clean: no uncommitted work
- has_uncommitted: has uncommitted changes
- has_stash: has stashed changes
- has_unpushed: has unpushed commits
- unknown: git check failed

This follows ZFC (Zero Figuring in Code) principles - the polecat is the
authority on its own state, not Go code inferring it from external signals.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 16:37:01 -08:00
Steve Yegge
213b3bab20 feat: Add atomic write pattern for state files (gt-wled7)
Prevents data loss from concurrent/interrupted state file writes by using
atomic write pattern (write to .tmp, then rename).

Changes:
- Add internal/util package with AtomicWriteJSON/AtomicWriteFile helpers
- Update witness/manager.go saveState to use atomic writes
- Update refinery/manager.go saveState to use atomic writes
- Update crew/manager.go saveState to use atomic writes
- Update daemon/types.go SaveState to use atomic writes
- Update polecat/namepool.go Save to use atomic writes
- Add comprehensive tests for atomic write utilities

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 15:57:53 -08:00
Steve Yegge
02d7b4ee0e test: Add polecat identity regression tests (gt-si6am, gt-y41ep)
Adds tests to prevent regression of polecat identity bugs:

1. TestInstallCLAUDETemplate: Verifies template is loaded from
   mayor/rig/templates/ (not rig root) with correct variable substitution.

2. TestInstallCLAUDETemplateNotAtRigRoot: Verifies templates at the
   old buggy location (rig root) are NOT used.

3. TestPolecatCommandFormat: Documents and verifies that polecat sessions
   export GT_ROLE=polecat, GT_RIG, GT_POLECAT, BD_ACTOR inline before
   starting Claude (because tmux SetEnvironment only affects new panes).

These tests ensure polecats correctly identify as polecats, not mayor.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-28 15:40:01 -08:00
Steve Yegge
b5a3fe3e15 fix: Polecat identity detection - template path and env export (gt-si6am, gt-y41ep, gt-9ar8x)
Two bugs caused polecats to think they were mayor:

1. Template lookup path (gt-si6am):
   - Was looking at rig.Path/templates/ which doesn't exist
   - Now correctly looks at mayor/rig/templates/
   - Polecats get the polecat CLAUDE.md instead of inheriting mayor's

2. Env var export (gt-y41ep):
   - tmux SetEnvironment only affects new panes, not current shell
   - Now exports GT_ROLE, GT_RIG, GT_POLECAT, BD_ACTOR inline before Claude
   - Matches how crew sessions work

Combined effect (gt-9ar8x): Polecats now correctly identify as polecats
and work from their own directory instead of mayor/rig.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-28 15:34:35 -08:00
Steve Yegge
bac6f084ff Wire polecat-CLAUDE.md template into polecat spawn (gt-34mxx)
Add installCLAUDETemplate() to Manager that:
- Reads templates/polecat-CLAUDE.md from rig root
- Substitutes {{rig}} and {{name}} with actual values
- Writes to polecats/<name>/CLAUDE.md

Called from both Add() and Recreate() after worktree creation.
Non-fatal if template is missing.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 12:59:54 -08:00
Steve Yegge
b4765c0c69 feat: Add polecat agent bead lifecycle (gt-rxa7v)
Create ephemeral agent beads for ZFC-compliant polecat state tracking.

- Add AgentFields struct and helpers to beads package
  - CreateAgentBead: Creates agent bead with role_type/rig/agent_state
  - UpdateAgentState: Updates agent_state and hook_bead fields
  - DeleteAgentBead: Hard-deletes ephemeral agent bead
  - GetAgentBead: Retrieves and parses agent bead

- Integrate lifecycle in polecat manager:
  - Add(): Creates gt-polecat-<rig>-<name> bead with state=spawning
  - Recreate(): Deletes old bead, creates fresh with state=spawning
  - RemoveWithOptions(): Deletes agent bead on nuke

This enables Witness to read polecat state from beads instead of
tmux scraping. State updates (spawning→working→done) are done by
polecats via bd agent state (separate beads CLI enhancement).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 01:37:22 -08:00
Steve Yegge
4730ac508f polecat: fresh unique branches per run, add gc command (gt-ake0m)
Changed polecat branch model to use unique timestamped branches
(polecat/<name>-<timestamp>) instead of reusing persistent branches.
This prevents JSONL drift issues where stale polecat branches don't
have recently created beads.

Changes:
- Add(): create unique branch, simplified (no reuse logic)
- Recreate(): create fresh branch, old ones left for GC
- loadFromBeads(): read actual branch from git worktree
- CleanupStaleBranches(): remove orphaned polecat branches
- ListBranches(pattern): new git helper for branch enumeration
- gt polecat gc: new command to clean up stale branches

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 17:19:02 -08:00
Steve Yegge
ce3ae5b18e fix: Don't persist namepool theme in state file
Theme is configuration (from settings/config.json), not runtime state.
Loading theme from state file was causing rig config to be ignored,
which is why the beads rig kept using mad-max names instead of minerals.
2025-12-27 14:19:14 -08:00
Steve Yegge
34b5a3bb8d Document intentional error suppressions with comments (gt-zn9m)
All 156 instances of _ = error suppression in non-test code now have
explanatory comments documenting why the error is intentionally ignored.

Categories of intentional suppressions:
- non-fatal: session works without these - tmux environment setup
- non-fatal: theming failure does not affect operation - visual styling
- best-effort cleanup - defer cleanup on failure paths
- best-effort notification - mail/notifications that should not block
- best-effort interrupt - graceful shutdown attempts
- crypto/rand.Read only fails on broken system - random ID generation
- output errors non-actionable - fmt.Fprint to io.Writer

This addresses the silent failure and debugging concerns raised in the
issue by making the intentionality explicit in the code.

Generated with Claude Code https://claude.com/claude-code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 23:14:29 -08:00