During rig initialization, now creates a .beads-ephemeral/ directory:
- Initialized as a git repo (for local versioning)
- Contains config.yaml with ephemeral: true
- Automatically added to rig .gitignore
This provides a local-only beads database for runtime tracking of
wisps and molecules, separate from the synced .beads/ database.
Closes gt-3x0z.1
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Witness shows polecat count under management (👁 N polecats)
- Refinery shows MQ length and processing status (🏭 MQ: N or 🏭 idle)
- Both show mail count when messages pending
Closes: gt-bd2l, gt-zayu
Checks whether the town root (~/gt) is under git version control.
Having the town harness in git is optional but recommended for:
- Backing up personal Gas Town configuration and history
- Tracking mail and coordination beads
- Easier federation across machines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes mail identity format from hyphenated (gastown-Toast) to
slash-based (gastown/polecats/Toast) to:
- Match directory structure (REST-like)
- Distinguish from hyphenated bead IDs (gt-xyz) and molecule names
Updated:
- addressToIdentity(): preserve slashes instead of replacing with dashes
- identityToAddress(): simplified, identity == address now
- detectSender(): include /polecats/ in polecat addresses
- Tests updated for new format
Closes gt-cxtu: shared beads architecture verified working.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added molecule workflow integration to Gas Town:
1. spawn.go: MoleculeContext in work assignment mail
- Shows step N/M and molecule ID in subject
- Includes molecule workflow instructions
- Guides polecat through DAG execution
2. prime.go: outputMoleculeContext()
- Detects if in-progress issue is a molecule step
- Shows molecule progress and next steps
- Displays molecule work loop instructions
3. molecule.go: 'gt molecule progress' command
- Shows execution progress for molecule root
- Displays done/in-progress/ready/blocked steps
- Progress bar and completion percentage
- JSON output for Witness automation
This enables polecats to work through molecule DAGs:
- Receive molecule-aware work assignments
- See context in gt prime output
- Follow DAG with 'bd ready --parent <root>'
- Witness can monitor with 'gt molecule progress'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running `gt crew at <name>` from inside the target session, we exec
Claude directly. Previously this meant we couldn't send `gt prime` afterward.
Now we pass "gt prime" as the initial prompt argument to the Claude CLI,
so Claude loads context immediately upon startup.
Closes gt-qivm
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When `gt mq submit` is run from a polecat work branch (polecat/<worker>/<issue>),
it now automatically triggers polecat shutdown after submitting the MR. The
polecat sends a lifecycle request to its Witness and waits for termination.
This eliminates the need for polecats to manually run `gt handoff --shutdown`
after completing work - they can just run `gt mq submit` and the cleanup
happens automatically.
Added `--no-cleanup` flag to disable auto-cleanup when needed (e.g., for
submitting multiple MRs or continuing work).
Closes gt-tca
🤖 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)
Implements gt-b2hj: Uses git fsck --unreachable to find orphaned commits
that were never merged to main.
Features:
- Filters to commits only (not blobs/trees)
- Date filtering (--days=N, default 7)
- Excludes stash commits (WIP on, index on, etc.)
- Excludes routine bd sync commits
- Shows recovery hints (cherry-pick, show, branch)
- docs/architecture.md: update mail routing explanation
- internal/witness/manager.go: fix actual bd mail calls to gt mail
- internal/cmd/mail.go: remove stale compatibility note
- internal/daemon/lifecycle.go: update comment
gt shutdown now performs full polecat cleanup after killing sessions:
- Removes worktrees
- Deletes polecat branches from mayor's clone
- Protects polecats with uncommitted work (refuses to clean)
Added --nuclear flag to force cleanup even with uncommitted work.
Closes gt-u1k
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move router and polecatAddress definitions before if block to avoid
shadowing (defining same vars inside and after the block)
- Handle branch deletion failure in Recreate() by checking if branch
still exists and using WorktreeAddExisting like Add() does
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Models often guess --version exists. Cobra provides both --version and -v
when Version is set on the root command.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes gt-9nf: gt spawn should create fresh polecat worktree, never reuse
Changes:
- Add Recreate() method to polecat manager that removes and recreates worktrees
- Modify spawn.go to always recreate existing polecats with fresh worktrees
- Preserves safety checks: blocks if polecat is working or has uncommitted work
- Use --force to bypass uncommitted work checks
This ensures polecats always start with the latest code from the base branch,
avoiding stale code, stale beads, and git history pollution.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The daemon verifies requesting_cycle=true in state.json before
executing lifecycle actions. For crew workers, the state file
must be at <townRoot>/<rig>/crew/<name>/state.json.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
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>
- 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>
- 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>
- 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>
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 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>
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>
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>
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>