Crew workers now use deacon for lifecycle management instead of
requiring manual session termination. When a crew worker runs
'gt handoff', it sends a lifecycle request to the deacon which
handles session kill/restart like it does for Mayor and Witness.
Changes:
- Route crew manager to deacon/ instead of "human"
- Add getCrewIdentity() to extract <rig>-crew-<name> from session
- Include full crew identity in LIFECYCLE subject for daemon parsing
- Remove special case that skipped lifecycle flow for crew
Also fixes pre-existing test failures in daemon/lifecycle_test.go
where BeadsMessage field names were out of sync with the struct.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bug: When daemon cycled a session, it verified requesting_cycle=true
but never cleared the flag after restart. This caused infinite
cycle loops on each heartbeat.
Also removed redundant SendKeysDelayed("gt prime") that injected
rogue text into terminal (SessionStart hook already handles priming).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The handoff command sends lifecycle requests via 'gt mail send' to
town-level beads, but the daemon was reading with 'bd mail inbox'
which reads from the local beads database. This fixes the mismatch.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Format is now "<Rig> Polecat <name>, checking in." and
"<Rig> Crew <name>, checking in." to match the pattern.
🤝 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Load() function wasn't reading the saved theme because the condition
p.Theme == "" was never true after NewNamePool() set it to "mad-max".
Now the loaded theme properly overrides constructor defaults.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extend the startup protocol to have all roles announce themselves:
- Mayor: "Mayor, checking in." (already present)
- Witness: "Witness, checking in."
- Polecat: "Polecat <name>, checking in."
- Refinery: "Refinery, checking in."
- Crew: "Crew <name>, checking in." (new case added)
This provides consistent startup behavior across all Gas Town agents.
🤝 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add crew session detection before polecat (gt-*-crew-* pattern)
- Crew workers exit immediately after sending handoff mail
- No waiting for manager since crew is human-managed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- mq.go (400): commands, flags, init, shared helpers
- mq_integration.go (606): integration branch create/land/status
- mq_status.go (357): status display and formatting
- mq_submit.go (219): submit command and branch parsing
- mq_list.go (206): list command and filtering
Also adds unit tests for helper functions:
- formatStatus, getStatusIcon, formatTimeAgo
- filterMRsByTarget with edge cases
- Test utilities for mocking beads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add y/N confirmation before shutdown (skip with --yes)
- Preserve crew sessions by default (include with --all)
- Add --polecats-only for minimal shutdown
- Show what will be stopped vs preserved before confirming
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The mail router was incorrectly routing rig-level addresses
(e.g., gastown/crew/max) to {rig}/.beads instead of town beads.
This caused mail to be invisible when agents checked their inbox.
Two-level beads architecture:
- ALL mail uses town beads ({townRoot}/.beads)
- Rig-level beads are for project issues only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add MIT LICENSE file
- Update version to 0.1.0
- Add mol-version-bump molecule for release workflow
- Terse README for OSS release
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new doctor checks:
1. persistent-role-branches: Detects crew/*, witness/rig, refinery/rig
directories not on main branch. Persistent roles should work directly
on main to avoid orphaned work.
2. beads-sync-orphans: Detects code changes on beads-sync branch that
weren't merged to main, catching cases where merges lose code changes.
Also adds ensureMainBranch() to crew attach to auto-switch persistent
roles to main at session start.
Closes gt-p9zh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The merge at 96c773f lost changes from 5791752 (beads-sync branch).
Re-implementing:
- router.go: Use bd create --type=message with labels
- mailbox.go: Use bd list/show/close instead of bd mail commands
- types.go: Add Pinned field to Message struct
Original work was in commits 5791752 and 4c060f4 on beads-sync.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When creating a polecat worktree, create a .beads/redirect file pointing
to the rig-level shared beads database. This eliminates git sync overhead
between polecats - they all connect to the same daemon and database.
Architecture:
gastown/
.beads/ <- Shared database (created if missing)
polecats/
nux/
.beads/
redirect <- Contains "../../.beads"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- daemon.go: Add SIGUSR1 handler to process lifecycle requests immediately
- handoff.go: Signal daemon after sending lifecycle mail to deacon/
- mail.go: Show message IDs in hook output for direct reading
Previously, gt handoff would wait up to 5 min for daemon heartbeat poll.
Now lifecycle requests are processed within milliseconds.
Closes gt-zut3
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd v0.32.0 removed mail commands. Updated gt mail to use:
- bd list --type message (inbox)
- bd show (read)
- bd close (delete/ack)
- bd create --type message (send)
Sender/thread/reply-to now stored in labels and extracted on read.
Added --pinned flag (blocked by bd pin bug gt-zr0a).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Crew workers are trusted maintainers who push directly to main:
- Own their clones (no isolation needed)
- Fast work cycles (10-15 min) make branch overhead wasteful
- Branches go stale with context cycling
- Polecats use branches/MRs; crew does not need review
Also updated two-level beads docs (removed stale rig-level references).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- molecule.go: Use findLocalBeadsDir() for project-level beads
- statusline.go: Use findMailWorkDir() for mail count (town beads)
Part of two-level beads architecture cleanup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace complex address-based routing with simple town root lookup.
All mail goes to ~/gt/.beads/ (town beads), eliminating the broken
rig-level routing.
Two-level model:
- Town beads (~/gt/.beads/): ALL mail and coordination
- Clone beads (<rig>/crew/*/.beads/): Project issues only
Fixes: gt-4qey
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Pinned field to Message and BeadsMessage types, and implement
sorting in listBeads() to show pinned messages first, then by
priority, then by date.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Pinned field to BeadsMessage and sort pinned messages before
unpinned ones in listBeads(). Within each group, sort by newest first.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace `bd mail send/inbox/read/ack` commands with `bd create/list/show/close`.
This separates the orchestration layer (gt) from the data plane (beads).
Changes:
- router.go: Use `bd create --type=message` instead of `bd mail send`
- mailbox.go: Use `bd list --type=message` and `bd show` for inbox/read
- types.go: Parse metadata from labels (from:, thread:, reply-to:)
- mail.go: Fix findBeadsWorkDir to prefer rig-level beads, fix crew address format
Messages are now stored as beads issues with type=message. Metadata (sender,
thread, reply-to) is stored in labels for retrieval.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add refinery and crew patterns to identityToSession()
- Add refinery and crew handling to restartSession() with pre-sync
- Add refinery and crew to identityToStateFile()
- Fix gt refinery start to send gt prime after Claude starts
- New syncWorkspace() helper for agents with persistent clones
Add comprehensive uncommitted work checks before any polecat cleanup:
- Check for uncommitted changes (modified/untracked files)
- Check for stashes
- Check for unpushed commits
Affected commands:
- gt polecat remove: now refuses if uncommitted work exists
- gt rig shutdown: checks all polecats before shutdown
- Witness cleanup: refuses to clean polecats with uncommitted work
- gt spawn: warns if spawning to polecat with uncommitted work
Safety model:
- --force: bypasses uncommitted changes check only
- --nuclear: bypasses ALL safety checks (will lose work)
New git helpers:
- StashCount(): count stashes in repo
- UnpushedCommits(): count commits not pushed to upstream
- CheckUncommittedWork(): comprehensive work status check
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --all flag to remove all polecats from a rig: `gt polecat remove gastown --all`
- Support multiple rig/polecat args: `gt polecat remove gastown/A gastown/B`
- Report summary of removed polecats and any failures
- Validate that --all is not used with rig/polecat format
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the core Witness functionality:
- gt witness start: Creates tmux session with Claude, theming, auto-priming
- gt witness stop: Kills tmux session and updates state
- gt witness status: Shows session state reconciled with tmux
- Shutdown handler: Verifies git clean state before cleanup, sends nudges
- Auto-spawn: Spawns polecats for ready work up to configurable capacity
- Health checks: Monitors polecat activity, nudges stuck workers, escalates
Also updates handoff to include polecat name in lifecycle requests.
Closes: gt-53w6, gt-mxyj, gt-5wtw, gt-cpm2, gt-es1i
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a polecat runs `gt handoff` (default: shutdown action), the current
branch is now automatically submitted to the merge queue if it follows
the polecat/<name>/<issue> naming convention.
This streamlines the polecat workflow:
- Work on assigned issue
- Commit changes
- Run `gt handoff` (automatically submits MR + retires)
The Refinery will process the merge request. If MR submission fails,
a warning is printed but handoff continues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement MoleculeCatalog for loading molecules from multiple sources:
1. Built-in molecules (shipped with the gt binary)
2. Town-level: <town>/.beads/molecules.jsonl
3. Rig-level: <rig>/.beads/molecules.jsonl
4. Project-level: .beads/molecules.jsonl
Changes:
- Add internal/beads/catalog.go with MoleculeCatalog type
- Update gt molecule list to show source (builtin, town, rig, project, database)
- Update gt molecule show to check catalog first, then database
- Update gt molecule instantiate to check catalog first
- Add gt molecule export command to export built-in molecules to JSONL
- Add --catalog and --db flags to gt molecule list
The catalog enables organizations to share molecule templates
independently of work item tracking, and allows customization
at different levels of the workspace hierarchy.
Closes gt-0ei3.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new health checks to gt doctor:
1. orphan-sessions: Detects Gas Town tmux sessions (gt-*) that do not
match expected patterns (mayor, deacon, rig-witness, rig-refinery,
rig-polecat). Validates rig names against actual workspace structure.
2. orphan-processes: Detects Claude/claude-code processes without a
tmux parent. Walks process tree to find orphaned instances that
may be consuming resources.
Both checks support --fix to clean up detected orphans:
- Kills orphaned tmux sessions
- Sends SIGINT (then SIGKILL) to orphaned processes
Closes gt-qsvq.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add `gt done` command as a convenience wrapper for polecats to signal
their work is ready for the merge queue. This addresses the missing
command referenced in polecat docs.
The command:
- Submits current branch to merge queue (same as gt mq submit)
- Auto-detects issue ID from branch name (polecat/<worker>/<issue>)
- Auto-detects integration branch if source issue has epic parent
- Provides polecat-friendly output messaging
Closes gt-qna4.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- gt-dsfi: Add periodic warning messages to handoff wait instead of
blocking forever with select{}. After 2 minutes, shows hints about
checking daemon/witness status and how to abort.
- gt-n7z7: Skip tmux session existence check when in foreground mode.
When background mode spawns foreground mode inside a tmux session,
the foreground check would find its own session and return "already
running". Now only checks PID when in foreground mode.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sync-branch setting is up to the project's .beads/config.yaml,
not something Gas Town should force. Projects can use bd doctor --fix
to configure sync-branch if they want multi-clone coordination.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New rigs now get sync-branch: beads-sync in their .beads/config.yaml
automatically. This enables multi-clone coordination for polecats,
crew members, and refinery.
Also added gt doctor check (beads-sync-branch) to verify existing rigs
have sync-branch configured, with --fix support.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add clear explanations of the town-level vs rig-level beads architecture:
- Town beads (~/gt/.beads): HQ coordination, no sync-branch
- Rig beads (in git clones): project work, uses beads-sync branch
- Clarify that rig-level .beads at container is gitignored
Updated:
- docs/architecture.md: New 'Two-Level Beads Architecture' section
- CLAUDE.md: Enhanced existing section with table and sync-branch info
- templates/roles/*.tmpl: Added beads architecture to crew, polecat, mayor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
In foreground mode, skip the tmux session check since we are likely
running inside the session that background mode created. Only check
PID to avoid self-detection.
Fixes the issue where gt refinery start gastown --foreground would
detect its own tmux session as already running.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The "hq-" prefix for town-level beads revealed that "HQ" (headquarters)
is a better name than "harness" for the top-level Gas Town structure.
- Renamed docs/harness.md to docs/hq.md with updated content
- Updated all documentation references in architecture.md and bootstrap.md
- Updated CLI help text and user-facing messages in install.go
- Updated gitinit.go with HQGitignore constant and HQ terminology
- Updated molecule templates in builtin_molecules.go
- Kept InitGitForHarness function name for backwards compatibility
HQ is more intuitive (where the mayor sits), fits the Mad Max aesthetic,
matches the beads prefix (hq-*), and is self-documenting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add molecule-first paradigm note at top of architecture.md
- Update all spawn examples to include --molecule flag
- Add "Config vs Molecule" section with cognition principle
- Add policy-to-molecule escalation note in federation-design.md
- Update role templates (mayor, witness) with molecule usage
Key message: Gas Town spawns workers on molecules, not just issues.
The issue is seed data; the molecule defines the workflow.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Key changes:
- Add gt nudge command for reliable Claude session messaging
- spawn.go now uses NudgeSession instead of SendKeysDebounced
- Fix templates test to match actual deacon template text
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The getManager() function was returning a literal "<rig>/witness" string
for polecats and refineries instead of substituting the actual rig name.
This caused LIFECYCLE messages to be sent to "@<rig>/witness" instead of
proper addresses like "@gastown/witness".
Fix:
- Add detectRigFromContext() to extract rig from current directory
- Update getManager() to use detected rig name
- Fallback to deacon/ if rig detection fails (safety)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement replaceable notifications to prevent heartbeat stacking when
agents are busy. Only the latest notification per slot is delivered.
Changes:
- Add NotificationManager for tracking pending notifications
- Add SendKeysReplace() that clears input line before sending
- Integrate slot tracking into daemon heartbeat pokes
- Mark notifications consumed when agent shows activity
The system tracks pending notifications in state files and skips
sending if a notification for the same slot is still pending.
When agent activity is detected (keepalive), slots are marked
consumed allowing new notifications to be sent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Encapsulates tmux send-keys with: literal mode, 500ms debounce, separate Enter.
Tested and reliable. Updates spawn.go to use NudgeSession.
Related: gt-1hf, gt-lz2
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of relying solely on hooks or witness coordination, spawn now:
- Waits 3 seconds for Claude Code to fully initialize
- Sends a direct nudge to the polecat to check inbox
- Still notifies Witness as backup monitoring
This provides immediate feedback to polecats without waiting for
witness response.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The SPAWN notification to Witness was going to rig-level beads,
but gt mail inbox checks town-level first. This caused messages
to get lost.
Fixes part of gt-c6b.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove hacky 5-second delay from spawn
- Send SPAWN notification to Witness after starting polecat session
- Witness uses AI to monitor polecat startup and nudge when ready
- Added SPAWN REQUEST PROCESSING section to Witness template
This implements event-driven polecat readiness detection (gt-hb0).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>