- Add internal/deps package for dependency management
- Check for bd before gt install and gt rig add
- Auto-install bd via go install if missing
- Version check warns if bd is too old (min: 0.43.0)
Closes#22🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change tmux from "optional" to "recommended for the full experience"
- Add "Enter the Mayor's office" step after gt rig add
- Explain Mayor role upfront in Core Concepts
- Reorder workflows to put Full Stack (Recommended) first
- Add example of conversational interaction with Mayor
- Document gt agents for session navigation
Closes#21🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GetAllRoleTemplates tests (basic and content validity)
- Add FixMultipleRigs test for multi-rig fix scenario
- Add DetailsFormat test verifying rig:template prefix format
- Add MalformedRigsJSON test for error handling
- Add EmptyRigsConfig test for edge case
- PatrolRolesHavePromptsCheck now verifies templates exist in each rig's
mayor clone at <rig>/mayor/rig/internal/templates/roles/
- Track missing templates by rig using missingByRig map
- Fix copies embedded templates to each rig's location
- Add GetAllRoleTemplates helper to templates package
- Add tests for no-rigs case and multiple-rigs scenarios
When the Refinery Engineer detects a merge conflict during rebase,
it now creates a dispatchable task bead for conflict resolution.
Task format:
- Title: Resolve merge conflicts: <original-issue-title>
- Type: task
- Priority: boosted from original (P2 -> P1, P1 -> P0)
- Description includes: original MR ID, branch, conflict SHA,
source issue, retry count, and step-by-step instructions
The task appears in bd ready and can be dispatched to available
polecats by the Witness. After resolution and force-push, the
Refinery will automatically retry the merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CHANGELOG.md: Initial release notes for v0.1.0
- .golangci.yml: Linter configuration adapted from beads
- RELEASING.md: Release process documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
initAgentBeads and crew_add were looking for beads at mayor/rig/.beads/
but during initial creation, beads is at rig root. The redirect
mechanism to mayor/rig/.beads/ gets set up later.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement ScoreMR function for merge queue priority ordering with:
- Convoy age factor (prevents starvation of old convoys)
- Priority factor (P0 beats P4)
- Retry penalty (prevents thrashing on conflict-prone MRs)
- MR age tiebreaker (FIFO within same priority)
Added fields to MR struct:
- RetryCount for conflict retry tracking
- ConvoyID and ConvoyCreatedAt for convoy linkage
Includes comprehensive unit tests and documentation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
buildAgentIdentity was returning 2-part format (rig/name) while
sling.go sets assignee using 3-part format (rig/polecats/name) from
session.AgentIdentity.Address(). This mismatch caused gt hook to
fail when querying for hooked beads by assignee.
Changes:
- buildAgentIdentity: Return rig/polecats/name for polecats
- buildAgentBeadID: Handle both 2-part and 3-part formats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update mol-refinery-patrol formula v4:
- Rename process-branch to "Mechanical rebase"
- Add robust conflict detection via exit codes
- Create conflict-resolution task on rebase failure
- Track conflict metadata (main SHA, branch SHA)
- Update loop-check with conflict-skip entry path
- Update generate-summary with conflict tracking
On conflicts: abort rebase, create task, preserve branch for resolution.
MR beads remain open until conflicts resolved and reprocessed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use conditional bindings (if-shell) to check if session name starts
with "gt-" before running Gas Town commands. For non-GT sessions:
- C-b n/p fall back to default next-window/previous-window
- C-b a shows a help message
This prevents Gas Town from hijacking keybindings in unrelated tmux
sessions that happen to share the same tmux server.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The TUI query used 'dependency_type' but the actual column is 'type'.
This caused expand to show nothing when pressing Enter on a convoy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements announce channel delivery in router.go:
- Add isAnnounceAddress() and parseAnnounceName() helpers
- Add ErrUnknownAnnounce error variable
- Add expandAnnounce() to load AnnounceConfig from messaging.json
- Add sendToAnnounce() for bulletin board delivery (single copy, no claiming)
- Add pruneAnnounce() for retention-based message cleanup
- Integrate announce routing in Send()
Announce channels store ONE copy of each message (unlike lists which fan-out).
Messages persist until retention limit is reached, with oldest messages
pruned automatically when limit is exceeded.
Also includes address helpers (gt-pn2fq dependency).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add announces subcommand to internal/cmd/mail.go that provides:
- gt mail announces: Lists all announce channels from messaging.json
- gt mail announces <channel>: Reads messages from a specific channel
The command queries beads for messages with announce_channel label and
displays them in reverse chronological order. Messages are NOT marked
as read or removed, preserving bulletin board semantics.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show ✓ for closed, ▶ for in_progress/hooked, ○ for other statuses
- Display assignee name in brackets instead of issue type
- Falls back to issue type when no assignee, or "unassigned" when neither
Closes gt-cbstf
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add announce address detection to internal/mail/router.go following
the same pattern as isListAddress/parseListName and isQueueAddress/
parseQueueName.
Added:
- isAnnounceAddress(address string) bool - returns true for 'announce:' prefix
- parseAnnounceName(address string) string - extracts channel name
- ErrUnknownAnnounce error variable
(gt-pn2fq)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New outputSessionMetadata() function prints a structured line at prime start:
[GAS TOWN] role:mayor pid:12345 session:abc-uuid-123
This enables gt seance to discover sessions from Claude transcripts,
complementing the existing event emission to .events.jsonl.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds `gt mail search <query>` command with:
- Regex pattern matching (case-insensitive by default)
- --from: Filter by sender address
- --subject: Only search subject lines
- --body: Only search message body
- --archive: Include archived (closed) messages
- --json: Output as JSON
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gt swarm create was failing when using a pre-existing epic because
it tried to call `bd update --mol-type=swarm`, but bd update doesn't
support the --mol-type flag.
Fix: Only set mol-type during bd create (when epic doesn't exist.
Pre-existing epics work as-is since swarm functionality doesn't
depend on the mol-type field.
Closes gt-zqt4d
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EOF
)
When -m flag is not provided, opens $EDITOR to compose the reply.
The editor shows a template with the original message for context.
Comment lines (starting with #) are filtered out.
- Makes -m flag optional instead of required
- Falls back to vim/vi/nano/emacs if $EDITOR not set
- Updates help text to document editor mode (gt-d46.5)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --quiet (-q) flag for scripted mail checks:
- Outputs "N new message(s)" only when mail exists
- Silent output when no mail (exit 1)
- Fixes usage output being shown on exit 1
(gt-d46.1)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- gt mail mark <id> --read/--unread: Change message read status
- gt mail delete <id> --force: Add confirmation prompt (skip with --force)
- gt mail archive: Batch operations with --older-than, --all-read, --dry-run
- gt mail purge: Delete archived messages with --older-than, --dry-run, --force
- gt mail search <query>: Regex search with --from, --subject, --body, --json
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The display was normalizing idle → working which was misleading.
Idle polecats should show as idle so operators know to nuke them.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The 10-minute recovery heartbeat was too slow to detect stuck agents promptly.
Reduced to 3 minutes for better balance between detection speed and overhead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The refinery template listed git branch -r | grep polecat as a reference
command, causing the refinery agent to check git branches instead of the
beads merge queue. This caused 41 MRs to pile up.
- Removed misleading git branch grep reference from Git Operations section
- Added explicit warnings about using gt mq list as sole source of truth
- Strengthened queue-scan step with CRITICAL warning
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add worker information to convoy status display:
- Query agent beads across rigs for matching hook_bead
- Display worker inline with tracked issues: @gastown/nux (12m)
- Include Worker and WorkerAge in JSON output
- Skip worker lookup for closed issues
Example output:
Tracked Issues:
○ gt-xyz: Fix bug [task] @gastown/nux (12m)
✓ gt-abc: Add feature [task]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use NoOptDefVal so --notify defaults to "mayor/" when specified without
a value:
- `--notify` (no arg) -> defaults to "mayor/"
- `--notify ops/` -> uses "ops/"
- (no flag) -> no notification
Removed the mayor-specific auto-default since NoOptDefVal handles this
for all roles.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement MachineRegistry that manages machine configurations and
provides Connection instances for local and remote operations:
- Machine struct with name, type, host, key path, and town path
- Registry with JSON persistence (federation.json)
- CRUD operations: Get, Add, Remove, List
- Connection factory that returns appropriate Connection type
- Built-in "local" machine that cannot be removed
SSH connections return an error until SSHConnection is implemented.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Define the Connection interface that abstracts file operations, command
execution, and tmux management for both local and remote (SSH) contexts.
Includes:
- Connection interface with file, exec, and tmux operations
- FileInfo interface for remote stat results
- BasicFileInfo implementation with JSON serialization
- Error types for connection failures
This enables Gas Town to manage rigs on remote machines using the
same interface as local operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use golang.org/x/text/cases.Title(language.English) instead of the
deprecated strings.Title function. Updated formula.go (3 usages)
and patrol_helpers.go (1 usage).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --collect/-c flag to gt handoff: auto-collects hooked work,
inbox summary, ready beads, and in-progress items into the handoff
message body
- Add --handoff flag to gt resume: checks inbox for messages with
"HANDOFF" in subject and displays them formatted for continuation
- Supports both JSON and plain-text inbox output formats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 7 new checks for rig health when using `gt doctor --rig <name>`:
- rig-is-git-repo: Verify mayor/rig/ is a valid git clone
- git-exclude-configured: Check .git/info/exclude has Gas Town dirs (fixable)
- witness-exists: Verify witness/ structure exists (fixable)
- refinery-exists: Verify refinery/ structure exists (fixable)
- mayor-clone-exists: Verify mayor/rig/ clone exists (fixable)
- polecat-clones-valid: Verify polecat directories are valid clones
- beads-config-valid: Verify beads configuration works (fixable)
Checks are only registered when --rig flag is provided.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update mol-sync-workspace generate-report step to distinguish:
- Feature branches: 'Commits ahead of main: N'
- Crew on main: 'Unpushed commits: N'
The 'commits ahead of main' was confusing for crew workers who work
directly on main branch. 'Unpushed commits' is clearer for that case.
Also added explicit git commands for checking divergence.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The monolithic handle-dirty-state step handled three distinct concerns.
Split into focused steps for clarity and maintainability:
1. handle-uncommitted: Handle staged/unstaged changes
- Commit if ready (WIP)
- Stash if experimental/incomplete
2. handle-untracked: Handle untracked files
- Decision matrix by file type
- Actions: gitignore, commit, or delete
- Warns against auto-delete
3. handle-stashes: Review and clean stash entries
- Age-based decision matrix
- Drop stale entries (>1 week old)
- Caution about index shifting
Updated cleanup-worktrees to depend on handle-stashes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>