- Add checkStaleAgents() to detect agents reporting "running" but not updating
- Add markAgentDead() to update agent bead state to "dead"
- Integrate stale agent check into heartbeat cycle
- DeadAgentTimeout set to 15 minutes
This is a safety mechanism for agents that crash without updating their state.
The daemon now marks them as dead so they can be restarted.
Also fixes duplicate AgentFields declaration - now uses beads.go version with
ParseAgentFieldsFromDescription alias in fields.go.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AgentFields and ParseAgentFieldsFromDescription to internal/beads/fields.go
- Update daemon/lifecycle.go to use shared parsing
- Update cmd/molecule_status.go to use shared parsing
- Remove duplicate parsing code and unused isAgentRunningByBead function
This consolidates agent bead field parsing in one place, following the pattern
established for AttachmentFields and MRFields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Add getAgentBeadState() and getAgentBeadInfo() to read agent state from beads
- Add identityToAgentBeadID() to map daemon identities to agent bead IDs
- Update ensureDeaconRunning() to check agent bead state first (ZFC compliant)
- Add agent bead state logging in executeLifecycleAction()
This is the first step toward ZFC-compliant state detection. Dependent tasks:
- gt-psuw7: Remove PID/tmux state inference
- gt-2hzl4: Add timeout fallback for dead agents
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This change migrates gt mol status from querying by pinned status + assignee
to reading the hook_bead field from agent beads.
Changes:
- Add AgentBeadFields struct to parse agent bead description fields
- Add buildAgentBeadID function to convert identity to agent bead ID
- Update runMoleculeStatus to:
1. First try to find the agent bead by ID
2. Read hook_bead from agent bead description
3. If hook_bead is set, fetch and display that bead
4. Fall back to legacy pinned-query approach if no agent bead or hook
The implementation is backwards compatible - agents without agent beads
(like polecats before gt-rxa7v is completed) still work via the fallback.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Raw tmux send-keys doesn't work correctly with Claude's input handling.
gt nudge uses literal mode + debounce + separate Enter for reliable delivery.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added ResolveBeadsDir() helper that follows .beads/redirect files,
enabling crew workers and polecats to properly access shared beads.
Updated callers:
- mailbox.go: NewMailboxFromAddress follows redirect
- catalog.go: LoadCatalog follows redirect at all levels
- doctor checks: beads_check, patrol_check, wisp_check follow redirect
Also added comprehensive tests for the redirect resolution logic.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a new fixable doctor check that verifies beads routing configuration:
- Checks if routes.jsonl exists
- Verifies all rigs have routing entries (by path, not just prefix)
- Validates that routes point to valid locations with .beads directories
- Can auto-fix by adding missing routes with --fix
The check is smart about prefix mismatches: if a rig already has a route
by path (e.g., gastown/mayor/rig), it won't report it as missing even if
the prefix in rigs.json differs from what's in routes.jsonl.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When mayor/deacon checks their hook from ~/gt, gt mol status now scans all
registered rigs for pinned beads. This ensures the propulsion principle works
regardless of which directory the agent starts in.
The scan uses routes.jsonl to find all rig beads directories.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When slinging or hooking work to mayor/deacon, the pin now lands in Town
beads (~/.beads/) instead of rig beads. This ensures gt mol status finds
the pinned work when run from ~/gt.
The issue was that town-level roles operate from the town root, so their
hooks should be discoverable from there.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The template incorrectly used --assignee flag on bd mol wisp which doesn't
exist. Changed to two-step pattern matching deacon template.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
When run in a non-crew session (Mayor, Witness, Refinery, Deacon),
gt crew next/prev now returns success (exit 0) instead of an error.
These sessions don't have cycle groups, so pressing C-b n should
simply do nothing rather than fail with an error message.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These methods called `bd pin` and `bd unpin` which have been removed.
Neither method was ever called - gt uses `bd update --status=pinned` instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --all flag to restart all running crew sessions
- Add --dry-run flag to preview without restarting
- Add --rig filter to target specific rig
- Extract restartCrewSession helper for reuse
🤝 Filed gt-1kljv for adding tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.