* fix: update test assertions and set BEADS_DIR in EnsureCustomTypes
- Update TestBuildAgentStartupCommand to check for 'exec env' instead
of 'export' (matches current BuildStartupCommand implementation)
- Add 'config' command handling to fake bd script in manager_test.go
- Set BEADS_DIR env var when running bd config in EnsureCustomTypes
to ensure bd operates on the correct database during agent bead creation
- Apply gofmt formatting
These fixes address pre-existing test failures on main.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: inject mock in TestRoleLabelCheck_NoBeadsDir for Windows CI
The test was failing on Windows CI because bd is not installed,
causing exec.LookPath("bd") to fail and return "beads not installed"
before checking for the .beads directory.
Inject an empty mock beadShower to skip the LookPath check, allowing
the test to properly verify the "No beads database" path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: regenerate formulas and fix unused parameter lint error
- Regenerate mol-witness-patrol.formula.toml to sync with source
- Mark unused hookName parameter with _ in installHookTo
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(tests): make Windows CI tests pass
- Skip symlink tests on Windows (require elevated privileges)
- Fix GT_ROOT assertion to handle Windows path escaping
- Use platform-appropriate paths in TestNewManager_PathConstruction
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix tests for quoted env and OS paths
* fix(test): add Windows batch scripts to molecule lifecycle tests
The molecule_lifecycle_test.go tests were failing on Windows CI because
they used Unix shell scripts (#!/bin/sh) for mock bd commands, which
don't work on Windows.
This commit adds Windows batch file equivalents for all three tests:
- TestSlingFormulaOnBeadHooksBaseBead
- TestSlingFormulaOnBeadSetsAttachedMoleculeInBaseBead
- TestDoneClosesAttachedMolecule
Uses the same pattern as writeBDStub() from sling_test.go for
cross-platform test mocks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(test): add Windows batch scripts to more tests
Adds Windows batch script equivalents to tests that use mock bd commands:
molecule_lifecycle_test.go:
- TestSlingFormulaOnBeadHooksBaseBead
- TestSlingFormulaOnBeadSetsAttachedMoleculeInBaseBead
- TestDoneClosesAttachedMolecule
sling_288_test.go:
- TestInstantiateFormulaOnBead
- TestInstantiateFormulaOnBeadSkipCook
- TestCookFormula
- TestFormulaOnBeadPassesVariables
These tests were failing on Windows CI because they used Unix shell
scripts (#!/bin/sh) which don't work on Windows.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(test): skip TestSlingFormulaOnBeadSetsAttachedMoleculeInBaseBead on Windows
The test's Windows batch script JSON output causes
storeAttachedMoleculeInBead to fail silently when parsing the bd show
response. This is a pre-existing limitation - the test was failing on
Windows before the batch scripts were added (shell scripts don't work
on Windows at all).
Skip this test on Windows until the underlying JSON parsing issue is
resolved.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: re-trigger CI after GitHub Internal Server Error
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Changes patrol-molecules-exist check to verify that patrol formulas
are accessible via `bd formula list` instead of looking for placeholder
molecule beads created by `bd create --type=molecule`.
## Problem
The check was looking for molecule-type beads with titles "Deacon Patrol",
"Witness Patrol", and "Refinery Patrol". These placeholder beads serve no
functional purpose because:
1. Patrols actually use `bd mol wisp mol-deacon-patrol` which cooks
formulas inline (on-the-fly)
2. The formulas already exist at the town level in .beads/formulas/
3. The placeholder beads are never referenced by any patrol code
## Solution
- Check for formula names (mol-deacon-patrol, mol-witness-patrol,
mol-refinery-patrol) instead of bead titles
- Use `bd formula list` instead of `bd list --type=molecule`
- Remove Fix() method that created unnecessary placeholder beads
- Update messages to reflect that formulas should exist in search paths
## Impact
- Check now verifies what patrols actually need (formulas)
- Eliminates creation of unnecessary placeholder beads
- More accurate health check for patrol system
Co-authored-by: Roland Tritsch <roland@ailtir.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Add Fix() method to SessionHookCheck to automatically update
settings.json files when 'gt prime' is used without '--hook'.
This enables 'gt doctor --fix' to repair existing installations
that use bare 'gt prime' in SessionStart/PreCompact hooks.
Changes:
- Changed SessionHookCheck to embed FixableCheck instead of BaseCheck
- Added filesToFix cache populated during Run()
- Implemented Fix() method that parses JSON and replaces 'gt prime'
with 'gt prime --hook' in command strings
- Uses json.Encoder with SetEscapeHTML(false) to preserve readable
ampersands in command strings
Closes: gt-1tj0c
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Update patrol_check tests to expect StatusOK instead of StatusWarning
for missing templates (embedded templates fill the gap)
- Add moveDir helper with cross-filesystem fallback for git clones
- Remove accidentally committed events.jsonl file
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The daemon creates hq-deacon and hq-mayor sessions (headquarters sessions)
that were incorrectly flagged as orphaned by gt doctor.
Changes:
- Update orphan session check to recognize hq-* prefix in addition to gt-*
- Update orphan process check to detect 'tmux: server' process name on Linux
- Add test coverage for hq-* session validation
- Update documentation comments to reflect hq-* patterns
This fixes the false positive warnings where hq-deacon session and its
child processes were incorrectly reported as orphaned.
Co-authored-by: Roland Tritsch <roland@ailtir.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
When Claude sessions were terminated using KillSession(), bash subprocesses
spawned by Claude's Bash tool could survive because they ignore SIGHUP.
This caused zombie processes to accumulate over time.
Changed all critical session termination paths to use KillSessionWithProcesses()
which explicitly kills all descendant processes before terminating the session.
Fixes: gt-ew3tk
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed findRuntimeProcesses() to only detect Claude processes that have
the --dangerously-skip-permissions flag. This is the signature of Gas Town
managed processes - user's personal Claude sessions don't use this flag.
Prevents false positives when users have personal Claude sessions running.
Closes#611
Co-Authored-By: dwsmith1983 <dwsmith1983@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add CheckMisclassifiedWisps doctor check to detect issues that should be
marked as wisps but aren't. This catches merge-requests, patrol molecules,
and operational work that lacks the wisp:true flag.
Add defense-in-depth wisp filtering to gt ready command. While bd ready
should already filter wisps, this provides an additional layer to ensure
ephemeral operational work doesn't leak into the ready work display.
Changes:
- New doctor check: misclassified-wisps (fixable, CategoryCleanup)
- gt ready now filters wisps from issues.jsonl in addition to scaffolds
- Detects wisp patterns: merge-request type, patrol labels, mol-* IDs
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add Windows stub for orphan cleanup
* Fix account switch tests on Windows
* Make query session events test portable
* Disable beads daemon in query session events test
* Add Windows bd stubs for sling tests
* Make expandOutputPath test OS-agnostic
* Make role_agents test Windows-friendly
* Make config path tests OS-agnostic
* Make HealthCheckStateFile test OS-agnostic
* Skip orphan process check on Windows
* Normalize sparse checkout detail paths
* Make dog path tests OS-agnostic
* Fix bare repo refspec config on Windows
* Add Windows process detection for locks
* Add Windows CI workflow
* Make mail path tests OS-agnostic
* Skip plugin file mode test on Windows
* Skip tmux-dependent polecat tests on Windows
* Normalize polecat paths and AGENTS.md content
* Make beads init failure test Windows-friendly
* Skip rig agent bead init test on Windows
* Make XDG path tests OS-agnostic
* Make exec tests portable on Windows
* Adjust atomic write tests for Windows
* Make wisp tests Windows-friendly
* Make workspace find tests OS-agnostic
* Fix Windows rig add integration test
* Make sling var logging Windows-friendly
* Fix sling attached molecule update ordering
---------
Co-authored-by: Johann Dirry <johann.dirry@microsea.at>
Adds a new doctor check that detects when beads routing.mode is set to
"auto" (or unset, which defaults to auto). In auto mode, beads uses
git remote URL to detect user role, and non-SSH URLs are interpreted
as "contributor" mode, which routes all writes to ~/.beads-planning
instead of the local .beads directory.
This causes mail and issues to silently go to the wrong location,
breaking inter-agent communication.
The check:
- Warns when routing.mode is not set or not "explicit"
- Is auto-fixable via `gt doctor --fix`
- References beads issue #1165 for context
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Phase 2: Daemon now uses config.LoadRoleDefinition() instead of role beads
- lifecycle.go: getRoleConfigForIdentity() reads from TOML configs
- Layered override resolution: builtin → town → rig
Phase 3: Remove role bead creation and references
- Remove RoleBead field from AgentFields struct
- gt install no longer creates role beads
- Remove 'role' from custom types list
- Delete migrate_agents.go (no longer needed)
- Deprecate beads_role.go (kept for reading existing beads)
- Rewrite role_beads_check.go to validate TOML configs
Existing role beads are orphaned but harmless.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add daemon.json creation to install.go (avoids patrol-hooks-wired warning)
- Change patrol-roles-have-prompts to StatusOK (templates are embedded in binary)
- Add boot directory creation to install.go (avoids warning on fresh install)
- Make boot-health check fixable via 'gt doctor --fix'
- Update FixHint to reference the fix command
The CloneDivergenceCheck was calling git fetch for each clone without
a timeout, causing gt doctor to hang indefinitely when network or
authentication issues occurred. Removed the fetch - divergence detection
now uses existing local refs (may be stale but won't block).
Fixes: gt-aoklf8
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When gt doctor runs, it now detects and kills zombie sessions - tmux
sessions that are valid Gas Town sessions (gt-*, hq-*) but have no
Claude/node process running inside. These occur when Claude exits or
crashes but the tmux session remains.
Previously, OrphanSessionCheck only validated session names but did not
check if Claude was actually running. This left empty sessions
accumulating over time.
Fixes#472
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sqlite3 to README.md prerequisites section
- Add gt doctor check that warns if sqlite3 CLI is not found
- Documents that sqlite3 is required for convoy database queries
Fixes#534
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(sling_test): update test for cook dir change
The cook command no longer needs database context and runs from cwd,
not the target rig directory. Update test to match this behavior
change from bd2a5ab5.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(tests): skip tests requiring missing binaries, handle --allow-stale
- Add skipIfAgentBinaryMissing helper to skip tests when codex/gemini
binaries aren't available in the test environment
- Update rig manager test stub to handle --allow-stale flag
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(config): remove BEADS_DIR from agent environment
Stop exporting BEADS_DIR in AgentEnv - agents should use beads redirect
mechanism instead of relying on environment variable. This prevents
prefix mismatches when agents operate across different beads databases.
Changes:
- Remove BeadsDir field from AgentEnvConfig
- Remove BEADS_DIR from env vars set on agent sessions
- Update doctor env_check to not expect BEADS_DIR
- Update all manager Start() calls to not pass BeadsDir
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): detect BEADS_DIR in tmux session environment
Add a doctor check that warns when BEADS_DIR is set in any Gas Town
tmux session. BEADS_DIR in the environment overrides prefix-based
routing and breaks multi-rig lookups - agents should use the beads
redirect mechanism instead.
The check:
- Iterates over all Gas Town tmux sessions (gt-* and hq-*)
- Checks if BEADS_DIR is set in the session environment
- Returns a warning with fix hint to restart sessions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Instead of changing the convoy ID format, register the hq-cv- prefix
as a valid route pointing to town beads. This preserves the semantic
meaning of convoy IDs (hq-cv-xxxxx) while fixing the prefix mismatch.
Changes:
- Register hq-cv- prefix during gt install
- Add doctor check and fix for missing convoy route
- Update routes_check tests for both hq- and hq-cv- routes
Fixes: gt-4nmfh
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Role beads (hq-*-role) are templates that define role characteristics.
They are created during gt install but creation may fail silently.
Without role beads, agents fall back to defaults.
Changes:
- Add beads.AllRoleBeadDefs() as single source of truth for role bead definitions
- Update gt install to use shared definitions
- Add doctor check that detects missing role beads (warning, not error)
- Doctor --fix creates missing role beads
Fixes#371
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): filter bd "Note:" messages from custom types check
bd outputs "Note: No git repository initialized..." to stdout when
running outside a git repo, which was contaminating the custom types
parsing and causing false warnings.
- Use Output() instead of CombinedOutput() to avoid stderr
- Filter out lines starting with "Note:" from stdout
Co-Authored-By: Claude <noreply@anthropic.com>
* test(doctor): add unit tests for custom types Note: filtering
Extract parseConfigOutput helper function and add tests verifying
that bd "Note:" informational messages are properly filtered from
config output. Tests fail without the fix and pass with it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude <noreply@anthropic.com>
* fix(beads): prevent routes.jsonl corruption from bd auto-export
When issues.jsonl doesn't exist, bd's auto-export mechanism writes
issue data to routes.jsonl, corrupting the routing configuration.
Changes:
- install.go: Create issues.jsonl before routes.jsonl at town level
- manager.go: Create issues.jsonl in rig beads; don't create routes.jsonl
(rig-level routes.jsonl breaks bd's walk-up routing to town routes)
- Add integration tests for routes.jsonl corruption prevention
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): add check to detect and fix rig-level routes.jsonl
Add RigRoutesJSONLCheck to detect routes.jsonl files in rig .beads
directories. These files break bd's walk-up routing to town-level
routes.jsonl, causing cross-rig routing failures.
The fix unconditionally deletes rig-level routes.jsonl files since
bd will auto-export to issues.jsonl on next run.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(rig): add verification that routes.jsonl does NOT exist in rig .beads
Add explicit test assertion and detailed comment explaining why rig-level
routes.jsonl files must not exist (breaks bd walk-up routing to town routes).
Also verify that issues.jsonl DOES exist (prevents bd auto-export corruption).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): ensure town root route exists in routes.jsonl
The RoutesCheck now detects and fixes missing town root routes (hq- -> .).
This can happen when routes.jsonl is corrupted or was created without the
town route during initialization.
Changes:
- Detect missing hq- route in Run()
- Add hq- route in Fix() when missing
- Handle case where routes.jsonl is corrupted (regenerate with town route)
- Add comprehensive unit tests for route detection and fixing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(beads): fix routing integration test for routes.jsonl corruption
The TestBeadsRoutingFromTownRoot test was failing because bd's auto-export
mechanism writes issue data to routes.jsonl when issues.jsonl doesn't exist.
This corrupts the routing configuration.
Fix: Create empty issues.jsonl after bd init to prevent corruption.
This mirrors what gt install does to prevent the same bug.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Role beads created by gt install were missing the gt:role label required
by GetRoleConfig(), causing witness startup to fail with:
"bead hq-witness-role is not a role bead (missing gt:role label)"
This regression was introduced in 96970071 which migrated from type-based
to label-based bead classification. The install code used raw exec.Command
instead of the beads API, so it wasn't updated to add labels.
Changes:
- Use bd.CreateWithID() API which auto-converts Type:"role" to gt:role label
- Add RoleLabelCheck doctor migration to fix existing installations
- Add comprehensive unit tests with mocked dependencies
Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Fix beads.run() to always explicitly set BEADS_DIR based on the working
directory or explicit override
- This prevents inherited environment variables (e.g., from mayor session
with BEADS_DIR=/home/erik/gt/.beads) from causing prefix mismatch errors
when creating agent beads for rigs
- Update polecat manager to use NewWithBeadsDir for explicitness
- Add comprehensive test coverage for BEADS_DIR routing and validation
- Add SessionLister interface for deterministic orphan session testing
Root cause: When BEADS_DIR was set in the parent environment, all bd
commands used the town database (hq- prefix) instead of the rig database
(gt- prefix), causing "prefix mismatch: database uses 'hq' but you
specified 'gt'" errors during polecat spawn.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes CI lint failures by handling unchecked error returns and marking
unused parameters with blank identifiers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The AGENTS.md file at rig level (e.g., gastown/AGENTS.md) should be a thin
bootstrap pointer (<20 lines), not full context. This adds a check in
checkRigPriming() to flag large AGENTS.md files, similar to how CLAUDE.md
is checked in checkAgentPriming().
Also fixes missing filepath import in beads.go that was breaking the build.
Closes: bd-mfrs6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 of dynamic priming subsystem:
1. PRIME.md provisioning for all workers (hq-5z76w, hq-ukjrr Part A)
- Added ProvisionPrimeMD to beads package with Gas Town context template
- Provision at rig level in AddRig() so all workers inherit it
- Added fallback provisioning in crew and polecat managers
- Created PRIME.md for existing rigs
2. Post-handoff detection to prevent handoff loop bug (hq-ukjrr Part B)
- Added FileHandoffMarker constant (.runtime/handoff_to_successor)
- gt handoff writes marker before respawn
- gt prime detects marker and outputs "HANDOFF COMPLETE" warning
- Marker cleared after detection to prevent duplicate warnings
3. Priming health checks for gt doctor (hq-5scnt)
- New priming_check.go validates priming subsystem configuration
- Checks: SessionStart hook, gt prime command, PRIME.md presence
- Warns if CLAUDE.md is too large (should be bootstrap pointer)
- Fixable: provisions missing PRIME.md files
This ensures crew workers get Gas Town context (GUPP, hooks, propulsion)
even if the gt prime hook fails, via bd prime fallback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Import beads' UX design system into gastown:
- Add internal/ui/ package with Ayu theme colors and semantic styling
- styles.go: AdaptiveColor definitions for light/dark mode
- terminal.go: TTY detection, NO_COLOR/CLICOLOR support
- markdown.go: Glamour rendering with agent mode bypass
- pager.go: Smart paging with GT_PAGER support
- Add colorized help output (internal/cmd/help.go)
- Group headers in accent color
- Command names styled for scannability
- Flag types and defaults muted
- Add gt thanks command (internal/cmd/thanks.go)
- Contributor display with same logic as bd thanks
- Styled with Ayu theme colors
- Update gt doctor to match bd doctor UX
- Category grouping (Core, Infrastructure, Rig, Patrol, etc.)
- Semantic icons (✓ ⚠ ✖) with Ayu colors
- Tree connectors for detail lines
- Summary line with pass/warn/fail counts
- Warnings section at end with numbered issues
- Migrate existing styles to use ui package
- internal/style/style.go uses ui.ColorPass etc.
- internal/tui/feed/styles.go uses ui package colors
Co-Authored-By: SageOx <ox@sageox.ai>
Two ZFC fixes:
1. Boot marker file (hq-zee5n): Changed IsRunning() to query
tmux.HasSession() directly instead of checking marker file
freshness with TTL. Removed stale marker check from doctor.
2. Branch pattern matching (hq-zwuh6): Replaced hardcoded "polecat/"
strings with constants.BranchPolecatPrefix for consistency.
Also removed 60-second WaitForCommand blocking from crew Start()
which was causing gt crew start to hang.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per ZFC principle: 'Let agents decide thresholds. Stuck is a judgment call.'
Changes:
- Add health check threshold fields to RoleConfig (ping_timeout,
consecutive_failures, kill_cooldown, stuck_threshold)
- Add LoadStuckConfig() to read thresholds from hq-deacon-role bead
- Update patrol_check.go to use configurable stuck threshold
- Defaults remain as fallbacks when no role bead config exists
Agents can now configure their stuck detection by adding fields to their
role bead, e.g.:
ping_timeout: 45s
consecutive_failures: 5
kill_cooldown: 10m
stuck_threshold: 2h
Fixes: hq-2355b
The env-vars check was using AgentEnvSimple which doesn't know the
actual TownRoot and BeadsDir paths. This could cause false positive
mismatches when comparing expected (empty paths) vs actual (real paths).
- Use config.AgentEnv with proper TownRoot and BeadsDir from CheckContext
- Rig-level roles resolve beads dir from rig path
- Update tests to use expectedEnv helper that generates full env vars
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The env-vars doctor check was skipping deacon with a stale comment
"it doesn't use standard env vars". After the AgentEnv refactor,
deacon/manager.go now uses config.AgentEnv() like all other roles.
- Remove the skip condition for deacon in env_check.go
- Update test from TestEnvVarsCheck_DeaconSkipped to test deacon is
actually checked (TestEnvVarsCheck_DeaconCorrect/DeaconMissing)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create centralized AgentEnv function as single source of truth for all
agent environment variables. All agents now consistently receive:
- GT_ROLE, BD_ACTOR, GIT_AUTHOR_NAME (role identity)
- GT_ROOT, BEADS_DIR (workspace paths)
- GT_RIG, GT_POLECAT/GT_CREW (rig-specific identity)
- BEADS_AGENT_NAME, BEADS_NO_DAEMON (beads config)
- CLAUDE_CONFIG_DIR (optional account selection)
Remove RoleEnvVars in favor of AgentEnvSimple wrapper.
Remove IncludeBeadsEnv flag - beads env vars always included.
Update all manager and cmd call sites to use AgentEnv.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a new `gt doctor` check that verifies tmux session environment
variables match expected values from `config.RoleEnvVars()`.
- Checks all Gas Town sessions (gt-*, hq-*)
- Compares actual tmux env vars against expected for each role
- Reports mismatches with guidance to restart sessions
- Treats no sessions as success (valid when Gas Town is down)
- Skips deacon (doesn't use standard env vars)
Also:
- Adds `tmux.GetAllEnvironment()` to retrieve all session env vars
- Removes redundant gtroot_check (env-vars check covers GT_ROOT)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add detection for when the installed gt binary is out of date with the
source repository. This helps catch issues where commands fail mysteriously
because the installed binary doesn't have recent fixes.
Changes:
- Add internal/version package with stale binary detection logic
- Add startup warning in PersistentPreRunE when binary is stale
- Add gt doctor check for stale-binary
- Use prefix matching for commit comparison (handles short vs full hash)
The warning is non-blocking and only shows once per shell session via
the GT_STALE_WARNED environment variable.
Resolves: gt-ud912
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add three layers of protection to prevent accidental branch switches in
the town root (~/gt), which should always stay on main:
1. Doctor check `town-root-branch`: Verifies town root is on main/master.
Fixable via `gt doctor --fix` to switch back to main.
2. Doctor check `pre-checkout-hook`: Verifies git pre-checkout hook is
installed. The hook blocks checkout from main to any other branch.
Fixable via `gt doctor --fix` or `gt git-init`.
3. Runtime warning in all gt commands: Non-blocking warning if town root
is on wrong branch, with fix instructions.
The root cause of this issue was git commands running in the wrong
directory, switching the town root to a polecat branch. This broke gt
commands because rigs.json and other configs were on main, not the
polecat branch.
Closes: hq-1kwuj
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive crash logging improvements to help diagnose mass session death events:
- Add TypeSessionDeath and TypeMassDeath event types for feed visibility
- Log pre-death events before killing sessions (who killed, why)
- Add mass death detection in daemon (3+ deaths in 30s triggers alert)
- Add macOS crash report check in gt doctor
- Support session death events in townlog and feed curator
Closes hq-kt1o6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add BeadsCustomTypes constant ("agent,role,rig,convoy,slot") to avoid
hardcoded strings scattered across the codebase
- Add CustomTypesCheck to gt doctor that verifies Gas Town custom types
are registered with beads, with --fix support
- Register custom types during gt init (best-effort, skips if no beads)
- Update install.go, rig_check.go, and rig/manager.go to use the constant
This ensures consistent type registration across all code paths and
catches misconfigured beads databases via gt doctor.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Bare clones don't have remote.origin.fetch set by default, which breaks
worktrees that need to fetch and see origin/* refs. This caused refinery
to fail because origin/main never appeared after fetch.
- Add configureRefspec() to set standard refspec on bare repos
- Call from CloneBare() and CloneBareWithReference()
- Add BareRepoRefspecCheck to doctor for existing rigs
Closes#286
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes polecat worktree structure from:
polecats/<name>/
to:
polecats/<name>/<rigname>/
This gives Claude Code agents a recognizable directory name (e.g., tidepool/)
in their cwd instead of just the polecat name, preventing confusion about
which repo they are working in.
Key changes:
- Add clonePath() method to manager.go and session_manager.go for the actual
git worktree path, keeping polecatDir() for existence checks
- Update Add(), RepairWorktree(), Remove() to use new structure
- Update daemon lifecycle and restart code for new paths
- Update witness handlers to detect both structures
- Update doctor checks (rig_check, branch_check, config_check,
claude_settings_check) for backward compatibility
- All code includes fallback to old structure for existing polecats
Fixes#283
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds support for alternative AI runtime backends (Codex, OpenCode) alongside
the default Claude backend through a runtime abstraction layer.
- internal/runtime/runtime.go - Runtime-agnostic helper functions
- Extended RuntimeConfig with provider-specific settings
- internal/opencode/ for OpenCode plugin support
- Updated session managers to use runtime abstraction
- Removed unused ensureXxxSession functions
- Fixed daemon.go indentation, updated terminology to runtime
Backward compatible: Claude remains default runtime.
Co-Authored-By: Ben Kraus <ben@cinematicsoftware.com>
Co-Authored-By: Cameron Palmer <cameronmpalmer@users.noreply.github.com>
When upgrading gt on an existing installation without .installed.json,
formulas that exist but don't match embedded were incorrectly marked as
"modified" (implying user customization). Now they're marked "untracked"
and are safe to update since there's no record of user modification.
This improves the upgrade experience:
- "modified" = tracked file user changed (skip update)
- "untracked" = file exists but not tracked (safe to update)
Adds 3 new tests for untracked scenarios.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds infrastructure to automatically update embedded formulas when
the binary is upgraded, while preserving user customizations.
Changes:
- Add CheckFormulaHealth() to detect outdated/modified/missing formulas
- Add UpdateFormulas() to safely update formulas via gt doctor --fix
- Track installed formula checksums in .beads/formulas/.installed.json
- Add FormulaCheck to gt doctor with auto-fix capability
- Compute checksums at runtime from embedded files (no build-time manifest)
Update scenarios:
- Outdated (embedded changed, user unchanged): Update automatically
- Modified (user customized): Skip with warning
- Missing (user deleted): Reinstall with message
- New (never installed): Install
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the hand-rolled contains() function with the standard library
strings.Contains(). Also removes the redundant len(data) > 0 check
since strings.Contains handles empty strings correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>