Two fixes in this commit:
1. daemon/lifecycle.go: Fix agent bead ID pattern for GUPP/orphaned work checks
- Wrong: gt-polecat-<rig>-<name> (e.g., gt-polecat-gastown-nux)
- Correct: <prefix>-<rig>-polecat-<name> (e.g., gt-gastown-polecat-nux)
- Use config.GetRigPrefix() instead of hardcoding gt prefix
- Use beads.ParseAgentBeadID() in extractRigFromAgentID
2. beads/beads.go: Fix invalid --add-label flag in bd create calls
- bd create uses --labels, not --add-label
- bd update uses --add-label (unchanged, was correct)
- Fixed Create, CreateWithID, CreateAgentBead, CreateRigBead
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per ZFC principle: 'Let agents decide thresholds. Stuck is a judgment call.'
Changes:
- Add health check threshold fields to RoleConfig (ping_timeout,
consecutive_failures, kill_cooldown, stuck_threshold)
- Add LoadStuckConfig() to read thresholds from hq-deacon-role bead
- Update patrol_check.go to use configurable stuck threshold
- Defaults remain as fallbacks when no role bead config exists
Agents can now configure their stuck detection by adding fields to their
role bead, e.g.:
ping_timeout: 45s
consecutive_failures: 5
kill_cooldown: 10m
stuck_threshold: 2h
Fixes: hq-2355b
- Use ResolveBeadsDir() to find beads.db in multi-worktree setups
where .beads/redirect points to the canonical beads location
- Add --allow-stale flag to bd sync command to handle cases where
the daemon is actively writing and staleness check would fail
Fixes hq-0cgd3
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>
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>
- 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.
The SetupRedirect function was failing for rigs that use the tracked
beads architecture where the canonical beads location is mayor/rig/.beads
and there is no rig-level .beads directory.
This fix now checks for both locations:
1. rig/.beads (with optional redirect to mayor/rig/.beads)
2. mayor/rig/.beads directly (if no rig/.beads exists)
This ensures crew and polecat workspaces get the correct redirect file
pointing to the shared beads database in all configurations.
Closes: gt-jy77g
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Cursor Agent as compatible agent for Gas Town
Add AgentCursor preset with ProcessNames field for multi-agent detection:
- AgentCursor preset: cursor-agent -p -f (headless + force mode)
- ProcessNames field on AgentPresetInfo for agent detection
- IsAgentRunning(session, processNames) in tmux package
- GetProcessNames(agentName) helper function
Closes: ga-vwr
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: centralize agent preset list in config.go
Replace hardcoded ["claude", "gemini", "codex"] arrays with calls to
config.ListAgentPresets() to dynamically include all registered agents.
This fixes cursor agent not appearing in `gt config agent list` and
ensures new agent presets are automatically included everywhere.
Also updated doc comments to include "cursor" in example lists.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add comprehensive agent client tests
Add tests for agent detection and command generation:
- TestIsAgentRunning: validates process name detection for all agents
(claude/node, gemini, codex, cursor-agent)
- TestIsAgentRunning_NonexistentSession: edge case handling
- TestIsClaudeRunning: backwards compatibility wrapper
- TestListAgentPresetsMatchesConstants: ensures ListAgentPresets()
returns all AgentPreset constants
- TestAgentCommandGeneration: validates full command line generation
for all supported agents
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Auggie agent, fix Cursor interactive mode
Add Auggie CLI as supported agent:
- Command: auggie
- Args: --allow-indexing
- Supports session resume via --resume flag
Fix Cursor agent configuration:
- Remove -p flag (requires prompt, breaks interactive mode)
- Clear SessionIDEnv (cursor uses --resume with chatId directly)
- Keep -f flag for force/YOLO mode
Updated all test cases for both agents.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(agents): add Sourcegraph AMP as agent preset
Add AgentAmp constant and builtinPresets entry for Sourcegraph AMP CLI.
Configuration:
- Command: amp
- Args: --dangerously-allow-all --no-ide
- ResumeStyle: subcommand (amp threads continue <threadId>)
- ProcessNames: amp
Closes: ga-guq
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: lint error in cleanBeadsRuntimeFiles
Change function to not return error (was always nil).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: beads v0.46.0 compatibility and test fixes
- Add custom types config (agent,role,rig,convoy,event) after bd init calls
- Fix tmux_test.go to use variadic IsAgentRunning signature
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: update agent documentation for new presets
- README.md: Update agent examples to show cursor/auggie, add built-in presets list
- docs/reference.md: Add cursor, auggie, amp to built-in agents list
- CHANGELOG.md: Add entry for new agent presets under [Unreleased]
Addresses PR #247 review feedback.
🤖 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>
Previously, SetupRedirect used os.RemoveAll() which deleted all files
in .beads/ including tracked files like formulas/, README.md, config.yaml.
Now cleanBeadsRuntimeFiles() selectively removes only gitignored runtime
files (*.db, daemon.*, issues.jsonl, etc.) while preserving tracked content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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
* 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>
Add AppendRouteToDir helper and use it to add hq-* route during rig
initialization. This allows rig beads to resolve role beads and other
hq-* prefixed beads stored in town beads.
Uses safe append pattern (load, merge, write) instead of overwriting
to avoid clobbering future rig routes.
Supersedes PR #184 with proper implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
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>
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>
Introduces a const TownBeadsPrefix = "hq" to centralize the town-level
beads prefix. Updates all hq- string literals in agent_ids.go to use
the constant, making prefix changes easier and reducing duplication.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1: Create agent_ids.go with town-level bead ID helpers
- MayorBeadIDTown(), DeaconBeadIDTown(), DogBeadIDTown()
- RoleBeadIDTown() and role-specific helpers (hq-*-role)
- Add deprecation notices to old gt-* prefix functions
Phase 2: Create town-level agent beads during gt install
- initTownAgentBeads() creates hq-mayor, hq-deacon agent beads
- Creates role beads: hq-mayor-role, hq-deacon-role, etc.
- Update rig/manager.go to use rig beads for Witness/Refinery
This aligns with the two-level beads architecture:
- Town beads (~/gt/.beads/): hq-* prefix for Mayor, Deacon, roles
- Rig beads (<rig>/.beads/): <prefix>-* for Witness, Refinery, Polecats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement two-level beads architecture for agent lookups:
- Town-level agents (Mayor, Deacon) now use hq- prefix and are
looked up in town beads (~/.beads/)
- Rig-level agents continue using rig prefix (e.g., gt-) and are
looked up in rig beads
Changes:
- Add MayorBeadIDTown(), DeaconBeadIDTown(), DogBeadIDTown() helpers
- Add GetTownBeadsPath() for town beads path resolution
- Update gt status to pre-fetch town-level agent beads
- Update agentIDToBeadID() to use town-level IDs
- Update agent_beads_check.go to check/fix in correct tier
- Update agentAddressToIDs() in deacon.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new helper functions for town-level agent bead IDs:
- MayorBeadIDTown() → "hq-mayor"
- DeaconBeadIDTown() → "hq-deacon"
- DogBeadIDTown(name) → "hq-dog-<name>"
- RoleBeadIDTown(role) → "hq-<role>-role"
These use the hq- prefix for town-level beads storage, distinct from
the gt- prefix used for rig-level beads.
Mark MayorBeadID() and DeaconBeadID() as deprecated in favor of the
new *Town() variants.
(gt-y24km)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements Phase 4 of the two-level beads architecture migration:
- Add hq- prefix helper functions for town-level agent beads
- Add CreateWithID method for deterministic bead creation
- Create gt migrate-agents command with dry-run/execute modes
- Migrate gt-mayor/gt-deacon to hq-mayor/hq-deacon in town beads
- Migrate role beads (gt-*-role) to town beads (hq-*-role)
- Add migration labels to old beads for tracking
- Idempotent: skips already-migrated beads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a crew or other agent dispatches work to a polecat using `gt sling`,
the polecat now tracks who dispatched the work and sends them a completion
notification when running `gt done`.
Changes:
- Add DispatchedBy field to AttachmentFields in beads/fields.go
- Store dispatcher agent ID in bead when slinging (both direct and formula)
- Check for dispatcher in done.go and send WORK_DONE notification to them
This fixes the orchestration issue where crews were left waiting because
polecats only notified the Witness on completion, not the dispatcher.
Fixes: id-c17
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds merge-slot integration to the Refinery's Engineer for serializing
conflict resolution. When a conflict is detected:
- Acquire the merge slot before creating a conflict resolution task
- If slot is held, defer task creation (MR stays in queue)
- Release slot after successful merge
This prevents cascading conflicts from multiple polecats racing to
resolve conflicts simultaneously.
Adds MergeSlot wrapper functions to beads package for slot operations.
(gt-4u49x)
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements priority scoring for merge queue ordering:
## Changes to gt mq list
- Add SCORE column showing priority score (higher = process first)
- Sort MRs by score descending instead of simple priority
- Add CONVOY column showing convoy ID if tracked
## New gt mq next command
- Returns highest-score MR ready for processing
- Supports --strategy=fifo for FIFO ordering fallback
- Supports --quiet for just printing MR ID
- Supports --json for programmatic access
## Changes to Refinery
- Queue() now sorts by priority score instead of simple priority
- Uses ScoreMR from mrqueue package for consistent scoring
## MR Fields Extended
- Added retry_count, last_conflict_sha, conflict_task_id
- Added convoy_id, convoy_created_at for convoy tracking
- These fields feed into priority scoring function
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for signaling phase completion when a polecat needs to wait
on a gate before continuing. The --phase-complete flag with --gate ID
allows polecats to hand off control while awaiting external conditions.
Changes:
- done.go: Add --phase-complete and --gate flags, PHASE_COMPLETE exit type
- protocol.go: Add Gate field to PolecatDonePayload
- handlers.go: Handle PHASE_COMPLETE by recycling session (keep worktree)
- beads.go: Add AddGateWaiter method for gate registration
This enables multi-phase molecule workflows with async coordination (bd-gxb4)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running bd update commands for hq-* beads from a polecat worktree,
the redirect mechanism only exposes gt-* beads. This fix sets BEADS_DIR
to the town-level .beads directory so hq-* beads are accessible.
Also adds NewWithBeadsDir() constructor to beads package for explicit
cross-database access when needed.
Add bd daemon health check at the start of gt status:
- Check daemon health via bd daemon health --json
- Attempt restart if daemons are unhealthy (version mismatch, stale, unresponsive)
- Show warning at end of status output if daemons could not be started
- Non-blocking: status display continues regardless of daemon state
This prevents the 39+ second slowdown when bd daemons are not running
properly, as each bd command falls back to slow direct mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements Do Not Disturb mode for Gas Town agents:
- Add notification_level to agent bead schema (verbose, normal, muted)
- gt dnd [on|off|status] - quick toggle for DND mode
- gt notify [verbose|normal|muted] - fine-grained control
- gt nudge checks target DND status, skips if muted
- --force flag on nudge to override DND
This allows agents (especially Mayor) to mute notifications
during focused work like swarm coordination.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pass CLAUDE_SESSION_ID environment variable to bd close for work attribution
tracking, enabling queries like "what work did this session do?" for entity
CV building (per decision 009-session-events-architecture.md).
Changes:
- beads.Close() and CloseWithReason() now pass --session to bd close
- Updated all direct exec.Command("bd", "close"...) calls:
- internal/mail/mailbox.go - closeInDir()
- internal/cmd/swarm.go - swarm land and cancel
- internal/cmd/hook.go - auto-replace completed beads
- internal/cmd/synthesis.go - convoy close
- internal/cmd/crew_lifecycle.go - workspace removal
- internal/cmd/polecat.go - polecat nuke
The bd CLI already supports --session (or CLAUDE_SESSION_ID env var) so
this change ensures consistent session tracking across all gt close paths.
Fixes: gt-nvz8b
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the synthesis step that combines leg outputs into a final
deliverable for convoy workflows:
- `gt synthesis start <convoy-id>` - Start synthesis after verifying
all legs are complete, collecting outputs, and slinging to polecat
- `gt synthesis status <convoy-id>` - Show synthesis readiness and
leg completion status
- `gt synthesis close <convoy-id>` - Close convoy after synthesis
Key features:
- Collects leg outputs from formula-defined paths (e.g., findings.md)
- Creates synthesis bead with combined context from all leg outputs
- Integrates with formula.toml synthesis configuration
- Provides TriggerSynthesisIfReady() for automated synthesis trigger
- Adds SynthesisFields struct for tracking synthesis state in beads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The unsling command had two bugs:
1. It used the local beads directory instead of the target agent's rig
2. It looked for status=hooked beads instead of the agent bead's hook_bead field
Changes:
- unsling.go: Rewrote to use agent bead's hook_bead field (matches how sling works)
- unsling.go: Now uses target agent's rig beads path, not local
- status.go: Prefer SQLite columns (issue.HookBead, issue.AgentState) over
parsing description text, with fallback for legacy beads
- beads.go: Added AgentState field to Issue struct for SQLite column access
This fixes the issue where `gt unsling gastown/crew/joe` would say "no work hooked"
even when gt status showed joe had a hook.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Key optimizations:
- Use --no-daemon for bd commands to avoid daemon IPC overhead
- Pre-fetch all agent beads in single query (ListAgentBeads)
- Pre-fetch all hook beads in single query (ShowMultiple)
- Pre-fetch all tmux sessions for O(1) lookup
- Parallel rig processing with goroutines
- Add --fast flag to skip mail lookups
The main bottleneck was bd daemon communication timing out on
stale daemon processes, causing 5+ second delays per rig.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When adding a dog, creates an agent bead with role_type:dog label.
When removing a dog, deletes the corresponding agent bead.
This enables @dogs group resolution in the mail router by allowing
queries like `bd list --type=agent --label=role_type:dog`.
Changes:
- Add DogBeadID(), DogRoleBeadID() helper functions
- Add CreateDogAgentBead() for creating dog agent beads with labels
- Add FindDogAgentBead() and DeleteDogAgentBead() for cleanup
- Add Labels field to Issue struct for label parsing
- Update ParseAgentBeadID() to handle dog bead IDs (gt-dog-<name>)
- Update IsAgentSessionBead() to include "dog" as valid role
(gt-qha0g)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add bidirectional cross-references between MR beads and agent beads:
1. MRFields.AgentBead - tracks which agent created the MR
2. AgentFields.ActiveMR - tracks agent's current MR
In gt done:
- Include agent_bead in MR description when creating
- Update agent bead with active_mr pointing to the new MR
In refinery merge handling:
- Clear agent bead's active_mr after successful merge
Benefits:
- Given MR, find which polecat created it
- Given polecat, find their active MR
- Orphan detection: MR without agent = stale
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Agent bead ID validation was hardcoded to only accept "gt-" prefix, which
caused errors when spawning beads polecats (which use "bd-" prefix):
Error: invalid agent ID: agent ID must start with 'gt-' (got "bd-beads-polecat-pearl")
Changed ParseAgentBeadID to accept any 2-3 character prefix (gt-, bd-, hq-)
instead of hardcoding "gt-". Updated tests to cover other prefixes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add FindMRForBranch helper to check for existing MR beads before creating.
If an MR already exists for the branch, skip creation and reuse it.
This makes gt done safe to re-run if interrupted mid-execution.
Implements Option C from gt-svdsy: idempotent operations that check
if already done before doing, making it safe to retry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create() function now defaults Actor from BD_ACTOR env var when not provided
- CreateAgentBead() now passes --actor flag from BD_ACTOR for provenance tracking
- This ensures created_by is populated on all issue creation paths
Affects: merge requests, escalations, digests, agent beads, molecule steps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Delegation and DelegationTerms structs for tracking work delegation
between work units. This enables the HOP pattern of work flowing down
and credit cascading up.
New types:
- Delegation: Links parent and child work units with delegated_by/to
- DelegationTerms: Optional terms including portion, deadline, credit_share
New functions:
- AddDelegation: Create a delegation relationship
- RemoveDelegation: Remove a delegation relationship
- GetDelegation: Retrieve delegation info for a child work unit
- ListDelegationsFrom: List all delegations from a parent
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements role-based lifecycle configuration where agent types self-register
via role beads instead of hardcoded identity string parsing in the daemon.
Changes:
- Add RoleConfig struct with lifecycle fields (session_pattern, work_dir_pattern,
needs_pre_sync, start_command, env_vars)
- Add ParseRoleConfig/FormatRoleConfig/ExpandRolePattern to beads package
- Add role bead ID helpers (RoleBeadID, MayorRoleBeadID, etc.)
- Refactor daemon to use single parseIdentity function as ONLY place where
identity strings are parsed
- Daemon now looks up role beads to get lifecycle config, with fallback to
defaults when role bead is missing or has no config
- Updated all role beads (mayor, deacon, witness, refinery, crew, polecat)
with structured lifecycle configuration fields
- Add comprehensive unit tests for RoleConfig parsing and expansion
This makes the daemon ZFC-compliant by trusting what agents self-report in
their role beads rather than encoding agent-specific knowledge in Go code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When spawning polecats in non-gastown rigs like beads, the agent bead ID
was incorrectly using the hardcoded "gt-" prefix instead of the rig's
configured prefix (e.g., "bd-" for beads).
Changes:
- Add GetPrefixForRig() in routes.go to look up prefix from routes.jsonl
- Update agentIDToBeadID() in sling.go to use rig's prefix via the new
*WithPrefix functions instead of hardcoded "gt"
- Add unit tests for the new functionality
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added multiple layers of protection against circular redirects:
1. ResolveBeadsDir now detects when a redirect points back to itself
and auto-removes the errant redirect file with a warning
2. ensureBeadsRedirect now includes safety checks:
- Prevents creating redirects inside mayor/rig/ (the canonical location)
- Validates that the redirect target is not the same as the beads dir
3. Added test case for circular redirect detection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, UpdateAgentState embedded hook_bead in the description
text field, while bd slot commands read/write from the SQLite
hook_bead column. This caused gt sling to report hooks as occupied
when bd slot show showed them empty.
Fix: Change UpdateAgentState to use proper bd commands:
- `bd agent state` for agent_state (updates column directly)
- `bd slot set/clear` for hook_bead (updates column directly)
This ensures consistency between gastown and beads commands.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>