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>
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>
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>
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>
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.
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>
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>
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>
Agent session molecules (gt-gastown-crew-joe, gt-gastown-witness, etc.)
update frequently for status tracking, creating noisy entries in the
activity feed. This change:
- Adds IsAgentSessionBead() to identify agent session beads
- Filters out "update" events for agent sessions from the event feed
- Still updates the agent tree so status is visible there
- Still shows create/complete/fail/delete events for agents
The filtering happens in addEvent() in the TUI feed model. Agent session
updates are identified by parsing the bead ID pattern and checking for
known agent roles (mayor, deacon, witness, refinery, crew, polecat).
Resolves: gt-sb6m4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
- Add HookBead and RoleBead fields to Issue struct for JSON unmarshal
- CreateAgentBead now calls bd slot set to set role slot properly
- This ensures role_bead is stored as a first-class field, not just
embedded in description text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Strip (gt-xxx), (bd-xxx) suffixes from code comments. The descriptions
remain meaningful without the ephemeral issue IDs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added comments explaining that RoleBead establishes a naming convention
for the canonical location of role definitions. The referenced bead may
not exist yet - this enables tooling like gt doctor to check for and
scaffold missing role beads.
🤖 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>
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>
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 CreatedBy field to Issue struct (matches beads GH#748)
- Add Actor field to CreateOptions, pass --actor to bd create
- Add ActorString() method to RoleInfo for identity formatting
- Update all beads.Create() callers to pass Actor
- Update direct bd create exec calls with --actor:
- mail/router.go: uses sender identity
- patrol_helpers.go: uses role name
- doctor/patrol_check.go: uses "gt-doctor"
- rig/manager.go: uses "gt-rig-init"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable Gas Town to operate without tmux by using beads for args transport:
- Add `attached_args` field to beads AttachmentFields
- gt sling: Store args in bead description, graceful fallback if no tmux
- gt prime: Display attached args prominently on startup
- gt mol status: Include attached_args in status output
- gt spawn --naked: Assign work via mail only, skip tmux session
Agents discover args via gt prime / bd show when starting manually.
Docs added explaining what works vs degraded behavior in no-tmux mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added comment explaining that the pinned field gets overwritten by
subsequent bd commands due to a bug in the beads auto-import logic.
The handoff bead attachment mechanism works correctly and is the
primary work assignment mechanism.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds Pin() and Unpin() methods to the beads wrapper that call bd pin/unpin.
Updates pinToHook() to call b.Pin() after AttachMolecule() to set the
pinned boolean field and assignee on the work issue. This should enable
bd hook to show pinned work.
NOTE: There's a known issue where bd pin via subprocess doesn't actually
set the pinned field even though it reports success. The handoff bead
attachment remains the primary mechanism until this is resolved.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement AttachmentFields to track molecule attachments on pinned/handoff beads:
- AttachedMolecule: root issue ID of attached molecule
- AttachedAt: timestamp when attached
API:
- AttachMolecule(pinnedBeadID, moleculeID) - attach
- DetachMolecule(pinnedBeadID) - detach
- GetAttachment(pinnedBeadID) - query
- ParseAttachmentFields(issue) - parse from description
- FormatAttachmentFields(fields) - format for description
Includes comprehensive tests for parsing and API.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Closes gt-48bs: gt rig reset now clears stale mail messages.
- Non-pinned messages are closed with reason 'Cleared during reset'
- Pinned messages have their content cleared but remain open
- Works with both --mail flag and default reset (all state)
Implement step recovery mechanism for stuck molecule steps (MVP):
- Add Release() and ReleaseWithReason() to beads wrapper
- Create gt release command to move in_progress → open
- Clears assignee so step can be claimed by another worker
- Optionally adds reason as note for tracking
Usage:
gt release <id> # Release single issue
gt release <id> -r "why" # Release with reason
This enables nondeterministic idempotence - stuck steps can be
safely recovered and retried by releasing and reclaiming.
Closes gt-g44u.4
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace polecat state.json with beads assignee field for state management:
- Remove state.json read/write from polecat.Manager
- Add loadFromBeads() to derive state from issue.assignee field
- Update AssignIssue() to set issue.assignee in beads
- Update ClearIssue() to clear assignee from beads
- Update SetState() to work with beads or gracefully degrade
- Add ListByAssignee and GetAssignedIssue to beads package
- Update spawn to create beads issues for free-form tasks
- Update tests for new beads-based architecture
State derivation:
- Polecat exists: worktree directory exists
- Polecat assigned: issue.assignee = 'rig/polecatName'
- Polecat working: issue.status = open/in_progress
- Polecat done: issue.status = closed or no assignee
Fixes: gt-qp98
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace mail-based handoff system with pinned beads that persist
across sessions. This fixes the issue where handoff messages get
closed before successors can read them.
Changes:
- beads: Add StatusPinned constant and handoff functions:
- HandoffBeadTitle() for well-known naming
- FindHandoffBead() to locate role handoff bead
- GetOrCreateHandoffBead() to ensure bead exists
- UpdateHandoffContent() to set handoff message
- ClearHandoffContent() to reset after reading
- cmd/handoff: Update to use pinned beads instead of mail
- sendHandoffMail() now updates pinned bead content
- cmd/prime: Display handoff content on startup
- outputHandoffContent() reads and shows handoff bead
- cmd/rig: Add reset command with --handoff flag
- gt rig reset --handoff clears handoff content
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds the Engineer component that polls for ready merge-requests and
processes them according to the merge queue design.
Features:
- Main loop that queries `bd ready` for merge-request type issues
- Configurable poll_interval and max_concurrent from rig config.json
- Graceful shutdown via context cancellation or Stop() method
- Claims MRs via `bd update --status=in_progress` before processing
- Handles success/failure with appropriate status updates
Configuration (in rig config.json merge_queue section):
- poll_interval: duration string (default "30s")
- max_concurrent: number (default 1)
- enabled, target_branch, run_tests, test_command, etc.
Also adds ReadyWithType() to beads package for type-filtered queries.
Note: ProcessMR() and handleFailure() are placeholders - full
implementation in gt-3x1.2 and gt-3x1.4.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>