Add explicit guidance on the Mayor → Crew → Polecats delegation model:
- Crew are coordinators for epics/goals needing decomposition
- Polecats are executors for well-defined tasks
- Include decision framework table for work type routing
Closes: gt-9jd
Implements the Overseer Experience epic (gt-k0kn):
- gt focus: Shows stalest high-priority goals, sorted by priority × staleness
- gt attention: Shows blocked items, PRs awaiting review, stuck workers
- gt status: Now includes GOALS and ATTENTION summary sections
- gt convoy list: Added --orphans, --epic, --by-epic flags
These commands reduce Mayor bottleneck by giving the overseer direct
visibility into system state without needing to ask Mayor.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add explicit guidance on the Mayor → Crew → Polecats delegation model:
- Crew are coordinators for epics/goals needing decomposition
- Polecats are executors for well-defined tasks
- Include decision framework table for work type routing
Closes: gt-9jd
Adds clear guidance that crew members are coordinators, not implementers:
- Lists 4 key responsibilities: Research, Decompose, Sling, Review
- Clarifies "goal-specific mayor" model - own outcomes via delegation
- Documents when to implement directly vs delegate (trivial fixes, spikes, etc.)
Closes: gt-gig
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add --convoy flag to gt sling that allows adding an issue to an existing
convoy instead of creating a new one. When specified:
- Validates the convoy exists and is open
- Adds tracking relation between convoy and issue
- Skips auto-convoy creation
Changes:
- Add slingConvoy variable and --convoy flag registration
- Add addToExistingConvoy() helper function in sling_convoy.go
- Modify auto-convoy logic to check slingConvoy first
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add flag variable declarations and Cobra flag registrations for:
- --epic: link auto-created convoy to parent epic
- --convoy: add to existing convoy instead of creating new
Closes: gt-n3o
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change molecule step completion instructions to use `gt mol step done`
instead of `bd close`. This ensures polecats get fresh context between
each step, which is critical for multi-step review workflows like
shiny-enterprise where each refinement pass should have unbiased attention.
The `gt mol step done` command already:
1. Closes the step
2. Finds the next ready step
3. Respawns the pane for fresh context
But polecats were being instructed to use `bd close` directly, which
skipped the respawn and let them run through entire workflows in a
single session with accumulated context.
Updated:
- prime_molecule.go: step completion instructions
- mol-polecat-work.formula.toml
- mol-polecat-code-review.formula.toml
- mol-polecat-review-pr.formula.toml
Fixes: hq-0kx7ra
Three fixes to make dog dispatch work end-to-end:
1. Add BuildDogStartupCommand in loader.go
- Similar to BuildPolecatStartupCommand/BuildCrewStartupCommand
- Passes AgentName to AgentEnv so BD_ACTOR is exported in startup command
2. Use BuildDogStartupCommand in dog.go
- Removes ineffective SetEnvironment calls (env vars set after shell starts
don't propagate to already-running processes)
3. Add "dog" case in mail_identity.go detectSenderFromRole
- Dogs now use BD_ACTOR for mail identity
- Without this, dogs fell through to "overseer" and couldn't find their mail
Tested: dog alpha now correctly sees inbox as deacon/dogs/alpha
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Recovered from reflog - these commits were lost during a rebase/force-push.
Dogs are directories with state files but no sessions. When `gt dog dispatch`
assigned work and sent mail, nothing executed because no session existed.
Changes:
1. Spawn tmux session after dispatch (gt-<town>-deacon-<dogname>)
2. Set BD_ACTOR=deacon/dogs/<name> so dogs can find their mail
3. Add dog case to AgentEnv for proper identity
Session spawn is non-blocking - if it fails, mail was sent and human can
manually start the session.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Dogs can now reset their own state to idle after completing work:
gt dog done # Auto-detect from BD_ACTOR
gt dog done alpha # Explicit name
This solves the issue where dog sessions would complete work but remain in
"working" state because nothing processed the DOG_DONE mail. Now dogs can
explicitly mark themselves idle before handing off.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes intermittent 'timeout waiting for runtime prompt' errors that occur
when Claude takes longer than 60s to start under load or on slower machines.
Resolves: hq-j2wl
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 of agent security model: Set distinct email addresses for each
agent type to improve audit trail clarity.
Email format:
- Town-level: {role}@gastown.local (mayor, deacon, boot)
- Rig-level: {rig}-{role}@gastown.local (witness, refinery)
- Named agents: {rig}-{role}-{name}@gastown.local (polecat, crew)
This makes git log filtering by agent type trivial and provides a
foundation for per-agent key separation in future phases.
Refs: hq-biot
Mayor now checks `gt escalate list` between hook and mail checks at startup.
This ensures pending escalations from other agents are handled promptly.
Other roles (witness, refinery, polecat, crew, deacon) are unaffected -
they create escalations but don't handle them at startup.
The daemon's isRigOperational() was only checking wisp config layer
for docked/parked status. However, 'gt rig dock' sets the status:docked
label on the rig identity bead (global/synced), not wisp config.
This caused the daemon to auto-restart agents on docked rigs because
it couldn't see the bead-level docked status.
Fix:
- Check rig bead labels for status:docked and status:parked
- Also updated mol-deacon-patrol formula to explicitly skip
DOCKED/PARKED rigs in health-scan step
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TestRoleAgentConfigWithCustomAgent tests custom agent "opencode-mayor"
which uses the opencode binary. Without the stub, the test falls back
to default and fails assertions about prompt_mode and env vars.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract platform-specific syscall code into proc_unix.go and proc_windows.go
with appropriate build tags. This fixes TestCrossPlatformBuild which failed
because syscall.SysProcAttr.Setpgid is Unix-only.
Changes:
- setSysProcAttr(): Sets process group on Unix, no-op on Windows
- isProcessAlive(): Uses Signal(0) on Unix, nil signal on Windows
- sendTermSignal(): SIGTERM on Unix, Kill() on Windows
- sendKillSignal(): SIGKILL on Unix, Kill() on Windows
Fixes gt-3078ed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gt hook status failed with "cannot determine agent identity (role: unknown)"
when run from rig root directories like ~/gt/beads. The cwd-based detection
only recognizes specific agent directories (witness/, polecats/foo/, etc.)
but not rig roots.
Now falls back to GT_ROLE env var when detectRole returns unknown, matching
the pattern used by GetRoleWithContext and other role detection code.
Fixes gt-6pg
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All agents now receive their startup beacon + role-specific instructions via
the CLI prompt, making sessions identifiable in /resume picker while removing
unreliable post-startup nudges.
Changes:
- Rename FormatStartupNudge → FormatStartupBeacon, StartupNudgeConfig → BeaconConfig
- Remove StartupNudge() function (no longer needed)
- Remove PropulsionNudge() and PropulsionNudgeForRole() functions
- Update deacon, witness, refinery, polecat managers to include beacon in CLI prompt
- Update boot to inline beacon (can't import session due to import cycle)
- Update daemon/lifecycle.go to include beacon via BuildCommandWithPrompt
- Update cmd/deacon.go to include beacon in startup command
- Remove redundant StartupNudge and PropulsionNudge calls from all startup paths
The beacon is now part of the CLI prompt which is queued before Claude starts,
making it more reliable than post-startup nudges which had timing issues.
SessionStart hook runs gt prime automatically, so PropulsionNudge was redundant.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When contributing to upstream repos or wanting human review before merge,
the --no-merge flag keeps polecat work on a feature branch instead of
auto-merging to main.
Changes:
- Add --no-merge flag to gt sling command
- Store no_merge field in bead's AttachmentFields
- Modify gt done to skip merge queue when no_merge is set
- Push branch and mail dispatcher "READY_FOR_REVIEW" instead
- Add tests for field parsing and sling flag storage
Closes: gt-p7b8
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(costs): read token usage from Claude Code transcripts instead of tmux
Replace tmux screen-scraping with reading token usage directly from Claude
Code transcript files at ~/.claude/projects/*/. This enables accurate cost
tracking by summing input_tokens, cache_creation_input_tokens,
cache_read_input_tokens, and output_tokens from assistant messages.
Adds model-specific pricing for Opus 4.5, Sonnet 4, and Haiku 3.5 to
calculate USD costs from token counts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(costs): correct Claude project path encoding
The leading slash should become a leading dash, not be stripped.
Claude Code encodes /Users/foo as -Users-foo, not Users-foo.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(costs): make --by-role and --by-rig fast by defaulting to today's costs
When using --by-role or --by-rig without a time filter, the command was
querying all historical events from the beads database via expensive bd list
and bd show commands, taking 10+ seconds and returning no data.
Now these flags default to today's costs from the log file (same as --today),
making them fast and showing actual data. This aligns with the new log-file-based
cost tracking architecture.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The polecat manager was using rig/name format while sling sets
rig/polecats/name. This caused gt polecat status to show 'done'
for working polecats because GetAssignedIssue couldn't find them.
Fixes gt-oohy
* fix(config): preserve all RuntimeConfig fields in fillRuntimeDefaults
fillRuntimeDefaults was only copying Command, Args, InitialPrompt, and Env
when creating a copy of RuntimeConfig. This caused fields like PromptMode,
Provider, Session, Hooks, Tmux, and Instructions to be silently dropped.
This broke custom agent configurations, particularly prompt_mode: "none"
which is needed for agents like opencode that don't accept a startup beacon.
Changes:
- Copy all RuntimeConfig fields in fillRuntimeDefaults
- Add comprehensive tests for fillRuntimeDefaults
- Add integration tests for custom agent configs with prompt_mode: none
- Add tests mirroring manual verification: claude-opus, amp, codex, gemini
* fix(config): deep copy slices and nested structs in fillRuntimeDefaults
The original fix preserved all fields but used shallow copies for slices
and nested structs. This could cause mutation of the original config.
Changes:
- Deep copy Args slice (was sharing backing array)
- Deep copy Session, Hooks, Tmux, Instructions structs (were pointer copies)
- Deep copy Tmux.ProcessNames slice
- Add comprehensive mutation isolation tests for all fields
- Fix TestMultipleAgentTypes to test actual built-in presets
- Add TestCustomClaudeVariants to clarify that claude-opus/sonnet/haiku
are NOT built-in and must be defined as custom agents
Built-in presets: claude, gemini, codex, cursor, auggie, amp, opencode
Custom variants like claude-opus need explicit definition in Agents map.
* docs(test): add manual test settings to TestRoleAgentConfigWithCustomAgent
Document the settings/config.json used for manual verification:
- default_agent: claude-opus
- Custom agents: amp-yolo, opencode-mayor (with prompt_mode: none)
- role_agents mapping for all 6 roles
- Manual test procedure for all 7 built-in agents
* fix(test): address CodeRabbit review feedback
- Fix isClaudeCommand to handle Windows paths and .exe extension
- Use isClaudeCommand helper instead of brittle equality check
- Add skipIfAgentBinaryMissing to tests that depend on external binaries
(TestMultipleAgentTypes, TestCustomAgentWithAmp)
* fix: always send handoff mail
* fix: remove trailing slash from mayor in detectSenderFromCwd
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Add functions to wake Claude Code's event loop in detached tmux sessions:
- IsSessionAttached: Check if session has attached clients
- WakePane: Always trigger SIGWINCH via resize dance
- WakePaneIfDetached: Smart wrapper that skips attached sessions
When Claude runs in a detached tmux session, its TUI library may not
process stdin until a terminal event occurs. Attaching triggers SIGWINCH
which wakes the event loop. WakePane simulates that by resizing the pane
down 1 row then back up.
NudgeSession and NudgePane now call WakePaneIfDetached after sending
Enter, covering all 22 nudge call sites in the codebase.
Fixes: gt-6s75ln
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The procps-ng kill binary (version 4.0.4+) has an argument parsing issue
where negative PIDs like "-12345" are misinterpreted as options because
they start with a dash. This causes the binary to fall back to "-1" which
means "all processes", resulting in kill(-1, signal) being called.
This was discovered through an extensive murder investigation after 26
Claude AI instances were killed when running TestCleanupOrphanedSessions.
Each investigator left notes for their successor, eventually leading to
the discovery that:
- exec.Command("bash", "-c", "kill -KILL -PGID") is SAFE (uses bash builtin)
- exec.Command("kill", "-KILL", "-PGID") is FATAL (uses /usr/bin/kill)
Verified via strace:
/usr/bin/kill -KILL -12345 → kill(-1, SIGKILL) # WRONG!
/usr/bin/kill -KILL -- -12345 → kill(-12345, SIGKILL) # Correct!
The fix adds "--" before negative PGID arguments to explicitly end option
parsing, ensuring the negative number is treated as a PID/PGID argument.
Full investigation: https://github.com/groblegark/gastown/blob/main/MURDER_INVESTIGATION.md
Co-authored-by: Refinery <matthew.baker@pihealth.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The ready command was incorrectly using RigMayorPath() which resolves to
<rig>/mayor/rig, causing BEADS_DIR to be set to a non-existent path like
/home/baldvin/gt/jbrs/mayor/rig/.beads instead of the actual database at
/home/baldvin/gt/jbrs/.beads.
This caused \"bd ready --json\" to fail with \"no beads database found\" when
called by gt ready, even though the database existed at the rig root.
Fix by using r.BeadsPath() which returns the rig root path. The beads
redirect system at <rig>/.beads/redirect already handles routing to
mayor/rig/.beads when appropriate.
Also updated getFormulaNames() and getWispIDs() calls to use the correct
path consistently.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
When nuking a polecat while your shell is cd'd into its worktree,
the shell becomes completely broken (even `echo hello` fails).
Add a check before deletion that detects if the current working
directory is inside the polecat's worktree. If so, return an error
with helpful instructions to cd elsewhere first.
The check runs ALWAYS, even with --force, because this is about
shell safety not data loss. You can't bypass it - just cd out first.
Fixes#942
gt handoff was calling KillPaneProcesses which killed Claude Code
(the pane process) before RespawnPane could be called. This caused
handoff to silently fail with no respawn.
Add KillPaneProcessesExcluding function that allows excluding specific
PIDs from being killed. The self-handoff path now excludes the current
process and its parent (Claude Code) so gt handoff survives long enough
to call RespawnPane. The -k flag on respawn-pane handles final cleanup.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(dashboard): comprehensive control panel with expand/collapse
- Add 13 panels: Convoys, Polecats, Sessions, Activity, Mail, Merge Queue,
Escalations, Rigs, Dogs, System Health, Open Issues, Hooks, Queues
- Add Mayor status banner and Summary/Alerts section
- Implement instant client-side expand/collapse (no page reload)
- Add responsive grid layout for different window sizes
- Parallel data fetching for faster load times
- Color-coded mail by sender, chronological ordering
- Full titles visible in expanded views (no truncation)
- Auto-refresh every 10 seconds via HTMX
* fix(web): update tests and lint for dashboard control panel
- Update MockConvoyFetcher with 11 new interface methods
- Update MockConvoyFetcherWithErrors with matching methods
- Update test assertions for new template structure:
- Section headers ("Gas Town Convoys" -> "Convoys")
- Work status badges (badge-green, badge-yellow, badge-red)
- CI/merge status display text
- Empty state messages ("No active convoys")
- Fix linting: explicit _, _ = for fmt.Sscanf returns
Tests and linting now pass with the new dashboard features.
* perf(web): add timeouts and error logging to dashboard
Performance and reliability improvements:
- Add 8-second overall fetch timeout to prevent stuck requests
- Add per-command timeouts: 5s for bd/sqlite3, 10s for gh, 2s for tmux
- Add helper functions runCmd() and runBdCmd() with context timeout
- Add error logging for all 14 fetch operations
- Handler now returns partial data if timeout occurs
This addresses slow loading and "stuck" dashboard issues by ensuring
commands cannot hang indefinitely.
agentBeadToAddress() expected gt- prefixed IDs but actual agent beads
use hq- prefix (e.g., hq-mayor instead of gt-mayor). This caused
"no agent found" errors when sending mail to valid addresses like mayor/.
- Add CreatedBy field to agentBead struct
- Handle hq-mayor and hq-deacon as town-level agents
- Use created_by field for rig-level agents (e.g., beads/crew/emma)
- Fall back to parsing description for role_type/rig fields
- Keep legacy gt- prefix handling for backwards compatibility
Closes: gt-1309e2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For self-handoff, calling KillPaneProcesses kills the gt handoff
process itself before it can execute RespawnPane, leaving the pane
dead with no respawn. The fix is to rely on respawn-pane -k which
handles killing and respawning atomically.
The remote handoff path is unaffected - it correctly calls
KillPaneProcesses because the caller is in a different session.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add `gt dolt` command with subcommands to manage the Dolt SQL server:
- start/stop/status: Control server lifecycle
- logs: View server logs
- sql: Open interactive SQL shell
- list: List available rig databases
- init-rig: Initialize new rig database
- migrate: Migrate from old .beads/dolt/ layout
The command detects both servers started via `gt dolt start` and
externally-started dolt processes by checking port 3307.
Closes: hq-05caeb
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously `make install` used `go install` which put the binary in ~/go/bin
without codesigning, while PATH used ~/.local/bin - causing chronic stale
binary issues. Now install depends on build (which codesigns on macOS) and
copies to the correct location.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove all bd sync references and SQLite-specific code from gastown:
**Formulas (agent priming):**
- mol-polecat-work: Remove bd sync step from prepare-for-review
- mol-sync-workspace: Replace sync-beads step with verify-beads (Dolt check)
- mol-polecat-conflict-resolve: Remove bd sync from close-beads
- mol-polecat-code-review: Remove bd sync from summarize-review and complete-and-exit
- mol-polecat-review-pr: Remove bd sync from complete-and-exit
- mol-convoy-cleanup: Remove bd sync from archive-convoy
- mol-digest-generate: Remove bd sync from send-digest
- mol-town-shutdown: Replace sync-state step with verify-state
- beads-release: Replace restart-daemons with verify-install (no daemons with Dolt)
**Templates (role priming):**
- mayor.md.tmpl: Update session end checklist to remove bd sync steps
- crew.md.tmpl: Remove bd sync references from workflow and checklist
- polecat.md.tmpl: Update self-cleaning model and session close docs
- spawn.md.tmpl: Remove bd sync from completion steps
- nudge.md.tmpl: Remove bd sync from completion steps
**Go code:**
- session_manager.go: Remove syncBeads function and call
- rig_dock.go: Remove bd sync calls from dock/undock
- crew/manager.go: Remove runBdSync, update Pristine function
- crew_maintenance.go: Remove bd sync status output
- crew.go: Update pristine command help text
- polecat.go: Make sync command a no-op with deprecation message
- daemon/lifecycle.go: Remove bd sync from startup sequence
- doctor/beads_check.go: Update fix hints and Fix to use bd import not bd sync
- doctor/rig_check.go: Remove sync status check, simplify BeadsConfigValidCheck
- beads/beads.go: Update primeContent to remove bd sync references
With Dolt backend, beads changes are persisted immediately to the sql-server.
There is no separate sync step needed.
Part of epic: hq-e4eefc (SQLite removal)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Gas Town uses Dolt exclusively. Remove all bd sync and bd daemon
references from agent priming, templates, formulas, and docs.
With Dolt backend:
- Beads changes are automatically persisted
- No manual sync needed (no bd sync)
- No daemon needed (no bd daemon)
Updated files:
- polecat-CLAUDE.md template
- Role templates (crew, mayor, polecat)
- Message templates (spawn, nudge)
- Formulas (polecat-work, sync-workspace, shutdown, etc.)
- Reference docs
Part of hq-4f2f0c: Remove bd sync/daemon from agent priming
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace direct sqlite3 CLI calls in getTrackedIssues and isTrackedByConvoy
with bd dep list commands that work with any beads backend (SQLite or Dolt).
- getTrackedIssues: Use bd dep list --direction=down --type=tracks --json
- isTrackedByConvoy: Use bd dep list --direction=up --type=tracks --json
This enables convoy commands to work with the Dolt backend.
Fixes: hq-e4eefc.2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove all code that calls bd daemon commands, as bd daemon functionality
has been removed from beads:
- Delete internal/beads/daemon.go (CheckBdDaemonHealth, StopAllBdProcesses, etc.)
- Delete internal/beads/daemon_test.go
- Delete internal/doctor/bd_daemon_check.go (BdDaemonCheck health check)
- Remove bd daemon health check from gt status
- Remove bd daemon stopping from gt down
- Remove bd daemon cleanup from gt install
- Remove BdDaemonCheck registration from gt doctor
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Raw `go build` produces unsigned binaries that macOS kills. Add a
BuiltProperly ldflag that make build sets, and check it at startup.
If missing, print an error directing users to use make build.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt handoff killed pane processes before respawning, the pane would
be destroyed (since remain-on-exit defaults to off), causing respawn-pane
to fail with "can't find pane" error.
Fix: Set remain-on-exit=on before killing processes, so the pane survives
process death and can be respawned. This restores tmux session reuse on
handoffs.
Changes:
- Add SetRemainOnExit method to tmux package
- Call SetRemainOnExit(true) before KillPaneProcesses in:
- Local handoff (runHandoff)
- Remote handoff (handoffRemoteSession)
- Mayor attach respawn (runMayorAttach)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add the ability to force dark or light mode colors for CLI output,
overriding the automatic terminal background detection.
Changes:
- Add CLITheme field to TownSettings for persisting preference
- Add GetThemeMode() and HasDarkBackground() to ui package for
theme detection with GT_THEME env var override
- Add ApplyThemeMode() to explicitly set lipgloss dark background
- Add 'gt theme cli' subcommand to view/set CLI theme preference
- Initialize theme in CLI startup (persistentPreRun)
- Add comprehensive tests for theme mode functionality
Usage:
- gt theme cli # show current theme
- gt theme cli dark # force dark mode
- gt theme cli light # force light mode
- gt theme cli auto # auto-detect (default)
- GT_THEME=dark gt status # per-command override
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Fixes#915
`gt convoy check` was failing to detect closed beads in external rig databases,
causing convoys to remain perpetually open despite tracked work being completed.
Changes:
- Modified getTrackedIssues() to parse external:rig:id format and track rig ownership
- Added getExternalIssueDetails() to query external rig databases by running bd show
from the rig directory
- Changed from issueIDs []string to issueRefs []issueRef struct to track both ID and
rig name for each dependency
The fix enables proper cross-rig convoy completion by querying the appropriate database
(town or rig) for each tracked bead's status.
Testing: Verified that convoy hq-cv-u7k7w tracking external:claycantrell:cl-niwe now
correctly detects the closed status and auto-closes the convoy.
- Add quality gates (lint, format, tests) as step 1 before committing
- Support both npm and Go project types
- Add explicit warning: "DO NOT commit if lint or tests fail"
- Explain why manual checks are needed (worktrees may not trigger hooks)
Fixes hq-lint1
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When sending mail notifications, the canonical address format (rig/name)
doesn't distinguish between crew workers (session: gt-rig-crew-name) and
polecats (session: gt-rig-name). This caused notifications to fail for
crew workers in other rigs.
Solution: Try both possible session IDs when the address is ambiguous,
using the first one that has an active session.
Supersedes PR #896 which only handled slash-to-dash conversion.
Fixes: gt-h5btjg
The 'gt namepool' command was showing 'mad-max' for all rigs because
it created the pool with defaults instead of loading config. This made
it impossible to see if a rig had custom theme settings.
Load config before creating the pool, matching the logic in manager.go
that actually spawns polecats. Theme and CustomNames come from
settings/config.json, not from the state file.
Co-authored-by: Claude <noreply@anthropic.com>
* fix(witness): detect and ignore stale POLECAT_DONE messages
Add timestamp validation to prevent witness from nuking newly spawned
polecat sessions when processing stale POLECAT_DONE messages from
previous sessions.
- Add isStalePolecatDone() to compare message timestamp vs session created time
- If message timestamp < session created time, message is stale and ignored
- Add unit tests for timestamp parsing and stale detection logic
Fixes#909
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(mail): add --stale flag to gt mail archive
Add ability to archive stale messages (sent before current session started).
This prevents old messages from cycling forever in patrol inbox.
Changes:
- Add --stale and --dry-run flags to gt mail archive
- Move stale detection helpers to internal/session/stale.go for reuse
- Add ParseAddress to parse mail addresses into AgentIdentity
- Add SessionCreatedAt to get tmux session start time
Usage:
gt mail archive --stale # Archive all stale messages
gt mail archive --stale --dry-run # Preview what would be archived
Co-Authored-By: GPT-5.2 Codex <noreply@openai.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: GPT-5.2 Codex <noreply@openai.com>