bd sync: 2025-12-23 22:30:36

This commit is contained in:
Steve Yegge
2025-12-23 22:30:36 -08:00
parent a7c843f72d
commit ecb1ba6fe3
2 changed files with 112 additions and 314 deletions

View File

@@ -144,7 +144,7 @@
{"id":"gt-59zd.1","title":"mol sling command: attach molecule to agent hook","description":"Add `gt mol sling \u003cmolecule-id\u003e` command to attach a molecule to the current agent's hook.\n\n## Behavior\n\n```bash\ngt mol sling mol-witness-patrol\n```\n\n1. Find agent identity from cwd (witness, polecat, crew, etc.)\n2. Find or create agent's handoff bead\n3. Attach molecule to handoff bead (attached_molecule field)\n4. Create root issue for this molecule instance\n5. Instantiate molecule steps under the root\n\n## Difference from mol attach\n\n- `mol attach` attaches to an existing pinned bead\n- `mol sling` creates a fresh instance for execution\n\n## Output\n\n```\n🧬 Slung mol-witness-patrol on gastown/witness\n Instance: gt-xyz (9 steps)\n First step: inbox-check\n```\n\n## Implementation\n\n- Reuse InstantiateMolecule from molecule.go\n- Create wrapper issue for the instance\n- Set attached_molecule on handoff bead","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:19:45.161282-08:00","updated_at":"2025-12-23T22:21:44.041626-08:00","closed_at":"2025-12-23T22:21:44.041626-08:00","close_reason":"Superseded by simpler design - mol sling not needed, witness instantiates patrol directly","dependencies":[{"issue_id":"gt-59zd.1","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:19:45.161784-08:00","created_by":"daemon"}]} {"id":"gt-59zd.1","title":"mol sling command: attach molecule to agent hook","description":"Add `gt mol sling \u003cmolecule-id\u003e` command to attach a molecule to the current agent's hook.\n\n## Behavior\n\n```bash\ngt mol sling mol-witness-patrol\n```\n\n1. Find agent identity from cwd (witness, polecat, crew, etc.)\n2. Find or create agent's handoff bead\n3. Attach molecule to handoff bead (attached_molecule field)\n4. Create root issue for this molecule instance\n5. Instantiate molecule steps under the root\n\n## Difference from mol attach\n\n- `mol attach` attaches to an existing pinned bead\n- `mol sling` creates a fresh instance for execution\n\n## Output\n\n```\n🧬 Slung mol-witness-patrol on gastown/witness\n Instance: gt-xyz (9 steps)\n First step: inbox-check\n```\n\n## Implementation\n\n- Reuse InstantiateMolecule from molecule.go\n- Create wrapper issue for the instance\n- Set attached_molecule on handoff bead","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:19:45.161282-08:00","updated_at":"2025-12-23T22:21:44.041626-08:00","closed_at":"2025-12-23T22:21:44.041626-08:00","close_reason":"Superseded by simpler design - mol sling not needed, witness instantiates patrol directly","dependencies":[{"issue_id":"gt-59zd.1","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:19:45.161784-08:00","created_by":"daemon"}]}
{"id":"gt-59zd.2","title":"mol progress: track dynamically bonded children","description":"Extend `gt mol progress` to show dynamically bonded children.\n\n## Current Behavior\n\n```\ngt mol progress gt-abc\n```\n\nShows progress through pre-defined steps from InstantiateMolecule.\n\n## New Behavior\n\nAlso show dynamically bonded children:\n\n```\n📊 Progress: mol-witness-patrol (gt-abc)\n\n Steps (9):\n ✓ inbox-check\n ✓ check-refinery\n ✓ load-state\n ◐ survey-workers (bonded 3 children)\n ○ aggregate (WaitsFor: all-children)\n ○ save-state\n ○ generate-summary\n ○ context-check\n ○ burn-or-loop\n\n Bonded Children (3):\n ✓ arm-toast (5/5 steps)\n ◐ arm-nux (3/5 steps)\n ○ arm-furiosa (0/5 steps)\n\n Progress: 4/9 steps, 3 arms (1 complete, 1 in-progress, 1 pending)\n```\n\n## Implementation\n\n1. Find children with bonded_to: \u003cparent-id\u003e in description\n2. Recursively get progress for each bonded child\n3. Aggregate into parent progress display","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:19:58.346108-08:00","updated_at":"2025-12-23T22:21:45.06843-08:00","closed_at":"2025-12-23T22:21:45.06843-08:00","close_reason":"Will be part of witness integration, not separate task","dependencies":[{"issue_id":"gt-59zd.2","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:19:58.346575-08:00","created_by":"daemon"}]} {"id":"gt-59zd.2","title":"mol progress: track dynamically bonded children","description":"Extend `gt mol progress` to show dynamically bonded children.\n\n## Current Behavior\n\n```\ngt mol progress gt-abc\n```\n\nShows progress through pre-defined steps from InstantiateMolecule.\n\n## New Behavior\n\nAlso show dynamically bonded children:\n\n```\n📊 Progress: mol-witness-patrol (gt-abc)\n\n Steps (9):\n ✓ inbox-check\n ✓ check-refinery\n ✓ load-state\n ◐ survey-workers (bonded 3 children)\n ○ aggregate (WaitsFor: all-children)\n ○ save-state\n ○ generate-summary\n ○ context-check\n ○ burn-or-loop\n\n Bonded Children (3):\n ✓ arm-toast (5/5 steps)\n ◐ arm-nux (3/5 steps)\n ○ arm-furiosa (0/5 steps)\n\n Progress: 4/9 steps, 3 arms (1 complete, 1 in-progress, 1 pending)\n```\n\n## Implementation\n\n1. Find children with bonded_to: \u003cparent-id\u003e in description\n2. Recursively get progress for each bonded child\n3. Aggregate into parent progress display","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:19:58.346108-08:00","updated_at":"2025-12-23T22:21:45.06843-08:00","closed_at":"2025-12-23T22:21:45.06843-08:00","close_reason":"Will be part of witness integration, not separate task","dependencies":[{"issue_id":"gt-59zd.2","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:19:58.346575-08:00","created_by":"daemon"}]}
{"id":"gt-59zd.3","title":"Witness: instantiate mol-witness-patrol on start","description":"When witness starts, create a mol-witness-patrol instance and pin it to the witness hook.\n\n## Changes to witness/manager.go\n\nIn Start() or run():\n1. Check if patrol instance exists on hook\n2. If not, call beads.InstantiateMolecule(mol-witness-patrol, handoffBead)\n3. Store instance ID for later reference\n\n## Hook Structure\n\nThe witness handoff bead gets:\n- attached_molecule: gt-patrol-xyz\n- attached_at: timestamp\n\n## Idempotency\n\nIf patrol already exists (from previous session), reuse it.\nDon't create duplicate instances on restart.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:21:55.247815-08:00","updated_at":"2025-12-23T22:28:08.650718-08:00","closed_at":"2025-12-23T22:28:08.650718-08:00","close_reason":"Implemented ensurePatrolInstance in witness manager. Creates mol-witness-patrol tracking instance on start, reuses existing if present.","dependencies":[{"issue_id":"gt-59zd.3","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:21:55.248279-08:00","created_by":"daemon"}]} {"id":"gt-59zd.3","title":"Witness: instantiate mol-witness-patrol on start","description":"When witness starts, create a mol-witness-patrol instance and pin it to the witness hook.\n\n## Changes to witness/manager.go\n\nIn Start() or run():\n1. Check if patrol instance exists on hook\n2. If not, call beads.InstantiateMolecule(mol-witness-patrol, handoffBead)\n3. Store instance ID for later reference\n\n## Hook Structure\n\nThe witness handoff bead gets:\n- attached_molecule: gt-patrol-xyz\n- attached_at: timestamp\n\n## Idempotency\n\nIf patrol already exists (from previous session), reuse it.\nDon't create duplicate instances on restart.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T22:21:55.247815-08:00","updated_at":"2025-12-23T22:28:08.650718-08:00","closed_at":"2025-12-23T22:28:08.650718-08:00","close_reason":"Implemented ensurePatrolInstance in witness manager. Creates mol-witness-patrol tracking instance on start, reuses existing if present.","dependencies":[{"issue_id":"gt-59zd.3","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:21:55.248279-08:00","created_by":"daemon"}]}
{"id":"gt-59zd.4","title":"Witness: bond mol-polecat-arm when discovering polecat","description":"When witness discovers a polecat during healthCheck(), bond a mol-polecat-arm child.\n\n## Changes to witness/manager.go\n\nIn healthCheck() when iterating polecats:\n1. Check if arm already exists for this polecat (arm-{name})\n2. If not, call: gt mol bond mol-polecat-arm --parent=$PATROL_ID --ref=arm-{name} --var polecat_name={name} --var rig={rig}\n3. Track arm issue ID in handoff state\n\n## Arm Lifecycle\n\n- Created when polecat first seen\n- Updated as inspection happens (nudges, state changes)\n- Closed when polecat cleaned up\n\n## Deduplication\n\nCheck handoffState.WorkerStates[name].ArmID before creating.\nNeeds: gt-59zd.3","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T22:22:05.718229-08:00","updated_at":"2025-12-23T22:22:05.718229-08:00","dependencies":[{"issue_id":"gt-59zd.4","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:05.718706-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.4","depends_on_id":"gt-59zd.3","type":"blocks","created_at":"2025-12-23T22:22:33.154977-08:00","created_by":"daemon"}]} {"id":"gt-59zd.4","title":"Witness: bond mol-polecat-arm when discovering polecat","description":"When witness discovers a polecat during healthCheck(), bond a mol-polecat-arm child.\n\n## Changes to witness/manager.go\n\nIn healthCheck() when iterating polecats:\n1. Check if arm already exists for this polecat (arm-{name})\n2. If not, call: gt mol bond mol-polecat-arm --parent=$PATROL_ID --ref=arm-{name} --var polecat_name={name} --var rig={rig}\n3. Track arm issue ID in handoff state\n\n## Arm Lifecycle\n\n- Created when polecat first seen\n- Updated as inspection happens (nudges, state changes)\n- Closed when polecat cleaned up\n\n## Deduplication\n\nCheck handoffState.WorkerStates[name].ArmID before creating.\nNeeds: gt-59zd.3","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-23T22:22:05.718229-08:00","updated_at":"2025-12-23T22:29:54.432814-08:00","dependencies":[{"issue_id":"gt-59zd.4","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:05.718706-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.4","depends_on_id":"gt-59zd.3","type":"blocks","created_at":"2025-12-23T22:22:33.154977-08:00","created_by":"daemon"}]}
{"id":"gt-59zd.5","title":"Witness: close arm when polecat completes","description":"When witness cleans up a polecat, close its mol-polecat-arm issue.\n\n## Changes to witness/manager.go\n\nIn cleanupPolecat():\n1. Get arm ID from handoffState.WorkerStates[name].ArmID\n2. If exists, call: bd close {armID} --reason='polecat cleaned up'\n3. Clear ArmID from handoff state\n\n## Arm Close Reasons\n\n- 'polecat cleaned up' - normal completion\n- 'polecat killed - stuck' - killed due to inactivity\n- 'polecat killed - escalated' - killed after Mayor escalation\n\n## State Update\n\nThe arm's description could be updated with final outcome before closing.\nNeeds: gt-59zd.4","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T22:22:15.542735-08:00","updated_at":"2025-12-23T22:22:15.542735-08:00","dependencies":[{"issue_id":"gt-59zd.5","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:15.543212-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.5","depends_on_id":"gt-59zd.4","type":"blocks","created_at":"2025-12-23T22:22:33.241115-08:00","created_by":"daemon"}]} {"id":"gt-59zd.5","title":"Witness: close arm when polecat completes","description":"When witness cleans up a polecat, close its mol-polecat-arm issue.\n\n## Changes to witness/manager.go\n\nIn cleanupPolecat():\n1. Get arm ID from handoffState.WorkerStates[name].ArmID\n2. If exists, call: bd close {armID} --reason='polecat cleaned up'\n3. Clear ArmID from handoff state\n\n## Arm Close Reasons\n\n- 'polecat cleaned up' - normal completion\n- 'polecat killed - stuck' - killed due to inactivity\n- 'polecat killed - escalated' - killed after Mayor escalation\n\n## State Update\n\nThe arm's description could be updated with final outcome before closing.\nNeeds: gt-59zd.4","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T22:22:15.542735-08:00","updated_at":"2025-12-23T22:22:15.542735-08:00","dependencies":[{"issue_id":"gt-59zd.5","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:15.543212-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.5","depends_on_id":"gt-59zd.4","type":"blocks","created_at":"2025-12-23T22:22:33.241115-08:00","created_by":"daemon"}]}
{"id":"gt-59zd.6","title":"mol progress: display bonded children in output","description":"Extend gt mol progress to show dynamically bonded children.\n\n## Current Output\n\nShows steps from original instantiation only.\n\n## New Output\n\nAlso show bonded children:\n\n Bonded Children (3):\n ✓ arm-toast (closed)\n ◐ arm-nux (open)\n ○ arm-furiosa (open)\n\n## Implementation\n\n1. Query for children with bonded_to: {parent-id} in description\n2. For each bonded child, show status (open/closed)\n3. Optionally show progress through child's steps\nNeeds: gt-59zd.5","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-23T22:22:28.008426-08:00","updated_at":"2025-12-23T22:22:28.008426-08:00","dependencies":[{"issue_id":"gt-59zd.6","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:28.008932-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.6","depends_on_id":"gt-59zd.5","type":"blocks","created_at":"2025-12-23T22:22:33.32542-08:00","created_by":"daemon"}]} {"id":"gt-59zd.6","title":"mol progress: display bonded children in output","description":"Extend gt mol progress to show dynamically bonded children.\n\n## Current Output\n\nShows steps from original instantiation only.\n\n## New Output\n\nAlso show bonded children:\n\n Bonded Children (3):\n ✓ arm-toast (closed)\n ◐ arm-nux (open)\n ○ arm-furiosa (open)\n\n## Implementation\n\n1. Query for children with bonded_to: {parent-id} in description\n2. For each bonded child, show status (open/closed)\n3. Optionally show progress through child's steps\nNeeds: gt-59zd.5","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-23T22:22:28.008426-08:00","updated_at":"2025-12-23T22:22:28.008426-08:00","dependencies":[{"issue_id":"gt-59zd.6","depends_on_id":"gt-59zd","type":"parent-child","created_at":"2025-12-23T22:22:28.008932-08:00","created_by":"daemon"},{"issue_id":"gt-59zd.6","depends_on_id":"gt-59zd.5","type":"blocks","created_at":"2025-12-23T22:22:33.32542-08:00","created_by":"daemon"}]}
{"id":"gt-5af","title":"Deacon: Hierarchical health-check orchestrator","description":"Replace daemon heartbeats with Deacon - an AI agent that keeps Gas Town running.\n\n## Core Concept\n\nThe Deacon is a **Claude agent** (not just a Go process) that:\n- Lives at town root in gt-deacon session\n- Has its own mailbox (deacon/ identity in town beads)\n- Is poked by a minimal Go daemon every ~60s (if idle)\n- Monitors Mayor and Witnesses proactively\n- Handles lifecycle requests (restart/cycle) from Mayor, Witnesses, AND Crew\n\n## Architecture\n\n```\nMinimal Go Daemon (just watches Deacon)\n |\n v\n Deacon (Claude agent)\n |\n +----+----+\n v v\n Mayor Witnesses --\u003e Polecats (Witness-managed)\n | |\n +----+----+\n |\n Crew (lifecycle only, not monitored)\n```\n\n## Deacon Responsibilities\n\n**Proactive monitoring:**\n- Mayor health (tmux session, keepalive freshness)\n- Witness health (tmux sessions, keepalive freshness)\n\n**Reactive lifecycle:**\n- Process restart/cycle requests from Mayor, Witnesses, Crew\n- Kill session, create new, prime, verify startup\n\n**Escalation:**\n- Mail human (configurable) if issues can't be resolved\n\n## Key Files\n\n- ~/gt/DEACON.md - Role context\n- ~/gt/deacon/ - State directory\n - heartbeat.json - Written each wake cycle (daemon checks this)\n - state.json - Health tracking, last scan results\n- ~/gt/.beads/ - Town beads with deacon/ mail identity\n\n## Wake Cycle\n\n1. Write heartbeat (prevents daemon from poking)\n2. Check mail (lifecycle requests)\n3. Quick health scan (Mayor, Witnesses)\n4. Process lifecycle requests\n5. Remediate unhealthy agents\n6. Update state\n\n## Session Patterns\n\n- Deacon: gt-deacon\n- Mayor: gt-mayor\n- Witness: gt-\u003crig\u003e-witness\n- Crew: gt-\u003crig\u003e-\u003cname\u003e (e.g., gt-gastown-max)\n\n## Relation to Policy Beads\n\nFuture: Deacon behavior configurable via policy beads (gt-3zw).\nInitial implementation uses sensible defaults.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-18T18:32:28.083305-08:00","updated_at":"2025-12-20T21:00:03.948543-08:00","closed_at":"2025-12-20T20:40:28.64361-08:00","dependencies":[{"issue_id":"gt-5af","depends_on_id":"gt-3zw","type":"blocks","created_at":"2025-12-18T18:32:36.617594-08:00","created_by":"daemon"}]} {"id":"gt-5af","title":"Deacon: Hierarchical health-check orchestrator","description":"Replace daemon heartbeats with Deacon - an AI agent that keeps Gas Town running.\n\n## Core Concept\n\nThe Deacon is a **Claude agent** (not just a Go process) that:\n- Lives at town root in gt-deacon session\n- Has its own mailbox (deacon/ identity in town beads)\n- Is poked by a minimal Go daemon every ~60s (if idle)\n- Monitors Mayor and Witnesses proactively\n- Handles lifecycle requests (restart/cycle) from Mayor, Witnesses, AND Crew\n\n## Architecture\n\n```\nMinimal Go Daemon (just watches Deacon)\n |\n v\n Deacon (Claude agent)\n |\n +----+----+\n v v\n Mayor Witnesses --\u003e Polecats (Witness-managed)\n | |\n +----+----+\n |\n Crew (lifecycle only, not monitored)\n```\n\n## Deacon Responsibilities\n\n**Proactive monitoring:**\n- Mayor health (tmux session, keepalive freshness)\n- Witness health (tmux sessions, keepalive freshness)\n\n**Reactive lifecycle:**\n- Process restart/cycle requests from Mayor, Witnesses, Crew\n- Kill session, create new, prime, verify startup\n\n**Escalation:**\n- Mail human (configurable) if issues can't be resolved\n\n## Key Files\n\n- ~/gt/DEACON.md - Role context\n- ~/gt/deacon/ - State directory\n - heartbeat.json - Written each wake cycle (daemon checks this)\n - state.json - Health tracking, last scan results\n- ~/gt/.beads/ - Town beads with deacon/ mail identity\n\n## Wake Cycle\n\n1. Write heartbeat (prevents daemon from poking)\n2. Check mail (lifecycle requests)\n3. Quick health scan (Mayor, Witnesses)\n4. Process lifecycle requests\n5. Remediate unhealthy agents\n6. Update state\n\n## Session Patterns\n\n- Deacon: gt-deacon\n- Mayor: gt-mayor\n- Witness: gt-\u003crig\u003e-witness\n- Crew: gt-\u003crig\u003e-\u003cname\u003e (e.g., gt-gastown-max)\n\n## Relation to Policy Beads\n\nFuture: Deacon behavior configurable via policy beads (gt-3zw).\nInitial implementation uses sensible defaults.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-18T18:32:28.083305-08:00","updated_at":"2025-12-20T21:00:03.948543-08:00","closed_at":"2025-12-20T20:40:28.64361-08:00","dependencies":[{"issue_id":"gt-5af","depends_on_id":"gt-3zw","type":"blocks","created_at":"2025-12-18T18:32:36.617594-08:00","created_by":"daemon"}]}
@@ -881,7 +881,7 @@
{"id":"gt-vhn1.1","title":"Polecat Arm (arm-toast)","description":"Single polecat inspection and action cycle.\n\nThis molecule is bonded dynamically by mol-witness-patrol's survey-workers step.\nEach polecat being monitored gets one arm that runs in parallel with other arms.\n\n## Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| polecat_name | Yes | Name of the polecat to inspect |\n| rig | Yes | Rig containing the polecat |\n\n## Step: capture\nCapture recent tmux output for toast.\n\n```bash\ntmux capture-pane -t gt-gastown-toast -p | tail -50\n```\n\nRecord:\n- Last activity timestamp (when was last tool call?)\n- Visible errors or stack traces\n- Completion indicators (\"Done\", \"Finished\", etc.)\n\n## Step: assess\nCategorize polecat state based on captured output.\n\nStates:\n- **working**: Recent tool calls, active processing\n- **idle**: At prompt, no recent activity\n- **error**: Showing errors or stack traces\n- **requesting_shutdown**: Sent LIFECYCLE/Shutdown mail\n- **done**: Showing completion indicators\n\nCalculate: minutes since last activity.\nNeeds: capture\n\n## Step: load-history\nRead nudge history for toast from patrol state.\n\n```\nnudge_count = state.nudges[toast].count\nlast_nudge_time = state.nudges[toast].timestamp\n```\n\nThis data was loaded by the parent patrol's load-state step and passed\nto the arm via the bonding context.\nNeeds: assess\n\n## Step: decide\nApply the nudge matrix to determine action for toast.\n\n| State | Idle Time | Nudge Count | Action |\n|-------|-----------|-------------|--------|\n| working | any | any | none |\n| idle | \u003c10min | any | none |\n| idle | 10-15min | 0 | nudge-1 (gentle) |\n| idle | 15-20min | 1 | nudge-2 (direct) |\n| idle | 20+min | 2 | nudge-3 (final) |\n| idle | any | 3 | escalate |\n| error | any | any | assess-severity |\n| requesting_shutdown | any | any | pre-kill-verify |\n| done | any | any | pre-kill-verify |\n\nNudge text:\n1. \"How's progress? Need any help?\"\n2. \"Please wrap up soon. What's blocking you?\"\n3. \"Final check. Will escalate in 5 min if no response.\"\n\nRecord decision and rationale.\nNeeds: load-history\n\n## Step: execute\nTake the decided action for toast.\n\n**nudge-N**:\n```bash\ntmux send-keys -t gt-gastown-toast \"{{nudge_text}}\" Enter\n```\n\n**pre-kill-verify**:\n```bash\ncd polecats/toast\ngit status # Must be clean\ngit log origin/main..HEAD # Check for unpushed\nbd show \u003cassigned-issue\u003e # Verify closed/deferred\n```\nIf clean: kill session, remove worktree, delete branch\nIf dirty: record failure, retry next cycle\n\n**escalate**:\n```bash\ngt mail send mayor/ -s \"Escalation: toast stuck\" -m \"...\"\n```\n\n**none**: No action needed.\n\nRecord: action taken, result, updated nudge count.\nNeeds: decide\n\n## Output\n\nThe arm completes with:\n- action_taken: none | nudge-1 | nudge-2 | nudge-3 | killed | escalated\n- result: success | failed | pending\n- updated_state: New nudge count and timestamp for toast\n\nThis data feeds back to the parent patrol's aggregate step.\n---\nbonded_from: mol-polecat-arm\nbonded_to: gt-vhn1\nbonded_ref: arm-toast\nbonded_at: 2025-12-23T10:00:00Z\n","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T22:27:56.71661-08:00","updated_at":"2025-12-23T22:27:56.888968-08:00","closed_at":"2025-12-23T22:27:56.888968-08:00","close_reason":"Closed","dependencies":[{"issue_id":"gt-vhn1.1","depends_on_id":"gt-vhn1","type":"parent-child","created_at":"2025-12-23T22:27:56.717145-08:00","created_by":"daemon"}]} {"id":"gt-vhn1.1","title":"Polecat Arm (arm-toast)","description":"Single polecat inspection and action cycle.\n\nThis molecule is bonded dynamically by mol-witness-patrol's survey-workers step.\nEach polecat being monitored gets one arm that runs in parallel with other arms.\n\n## Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| polecat_name | Yes | Name of the polecat to inspect |\n| rig | Yes | Rig containing the polecat |\n\n## Step: capture\nCapture recent tmux output for toast.\n\n```bash\ntmux capture-pane -t gt-gastown-toast -p | tail -50\n```\n\nRecord:\n- Last activity timestamp (when was last tool call?)\n- Visible errors or stack traces\n- Completion indicators (\"Done\", \"Finished\", etc.)\n\n## Step: assess\nCategorize polecat state based on captured output.\n\nStates:\n- **working**: Recent tool calls, active processing\n- **idle**: At prompt, no recent activity\n- **error**: Showing errors or stack traces\n- **requesting_shutdown**: Sent LIFECYCLE/Shutdown mail\n- **done**: Showing completion indicators\n\nCalculate: minutes since last activity.\nNeeds: capture\n\n## Step: load-history\nRead nudge history for toast from patrol state.\n\n```\nnudge_count = state.nudges[toast].count\nlast_nudge_time = state.nudges[toast].timestamp\n```\n\nThis data was loaded by the parent patrol's load-state step and passed\nto the arm via the bonding context.\nNeeds: assess\n\n## Step: decide\nApply the nudge matrix to determine action for toast.\n\n| State | Idle Time | Nudge Count | Action |\n|-------|-----------|-------------|--------|\n| working | any | any | none |\n| idle | \u003c10min | any | none |\n| idle | 10-15min | 0 | nudge-1 (gentle) |\n| idle | 15-20min | 1 | nudge-2 (direct) |\n| idle | 20+min | 2 | nudge-3 (final) |\n| idle | any | 3 | escalate |\n| error | any | any | assess-severity |\n| requesting_shutdown | any | any | pre-kill-verify |\n| done | any | any | pre-kill-verify |\n\nNudge text:\n1. \"How's progress? Need any help?\"\n2. \"Please wrap up soon. What's blocking you?\"\n3. \"Final check. Will escalate in 5 min if no response.\"\n\nRecord decision and rationale.\nNeeds: load-history\n\n## Step: execute\nTake the decided action for toast.\n\n**nudge-N**:\n```bash\ntmux send-keys -t gt-gastown-toast \"{{nudge_text}}\" Enter\n```\n\n**pre-kill-verify**:\n```bash\ncd polecats/toast\ngit status # Must be clean\ngit log origin/main..HEAD # Check for unpushed\nbd show \u003cassigned-issue\u003e # Verify closed/deferred\n```\nIf clean: kill session, remove worktree, delete branch\nIf dirty: record failure, retry next cycle\n\n**escalate**:\n```bash\ngt mail send mayor/ -s \"Escalation: toast stuck\" -m \"...\"\n```\n\n**none**: No action needed.\n\nRecord: action taken, result, updated nudge count.\nNeeds: decide\n\n## Output\n\nThe arm completes with:\n- action_taken: none | nudge-1 | nudge-2 | nudge-3 | killed | escalated\n- result: success | failed | pending\n- updated_state: New nudge count and timestamp for toast\n\nThis data feeds back to the parent patrol's aggregate step.\n---\nbonded_from: mol-polecat-arm\nbonded_to: gt-vhn1\nbonded_ref: arm-toast\nbonded_at: 2025-12-23T10:00:00Z\n","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T22:27:56.71661-08:00","updated_at":"2025-12-23T22:27:56.888968-08:00","closed_at":"2025-12-23T22:27:56.888968-08:00","close_reason":"Closed","dependencies":[{"issue_id":"gt-vhn1.1","depends_on_id":"gt-vhn1","type":"parent-child","created_at":"2025-12-23T22:27:56.717145-08:00","created_by":"daemon"}]}
{"id":"gt-vjv","title":"Add bulk session stop command (gt session stop --all)","description":"When decommissioning a rig, need to stop multiple sessions one at a time. A --all or --rig flag would allow: gt session stop --rig gastown","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-18T11:33:33.394649-08:00","updated_at":"2025-12-18T11:38:51.399298-08:00","closed_at":"2025-12-18T11:38:51.399298-08:00"} {"id":"gt-vjv","title":"Add bulk session stop command (gt session stop --all)","description":"When decommissioning a rig, need to stop multiple sessions one at a time. A --all or --rig flag would allow: gt session stop --rig gastown","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-12-18T11:33:33.394649-08:00","updated_at":"2025-12-18T11:38:51.399298-08:00","closed_at":"2025-12-18T11:38:51.399298-08:00"}
{"id":"gt-vjw","title":"Swarm learning: Session cleanup missing from swarm workflow","description":"## Problem\n\nAfter Enders Game swarm completed (18 issues merged), 16 polecat sessions were left running but idle. No automated cleanup occurred.\n\n## What Should Happen\n\n1. Witness detects polecat completed work (idle at prompt)\n2. Witness verifies git state is clean\n3. Witness shuts down session\n4. Witness reports completion to Mayor\n\n## GGT Components\n\n- gt-cxx: Witness context cycling (covers self-cycling)\n- gt-u1j.9: Witness daemon heartbeat loop\n- gt-kmn.6: Witness swarm landing protocol\n\n## Recommendation\n\nAdd to Witness responsibilities:\n- Monitor for 'work complete' signals (DONE keyword, idle detection)\n- Automated session shutdown after verification\n- Swarm completion reporting to Mayor\n\nSee also: architecture.md 'Worker Cleanup (Witness-Owned)' section which describes this but it wasn't implemented in PGT.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-16T01:27:52.796587-08:00","updated_at":"2025-12-16T01:51:37.409965-08:00","closed_at":"2025-12-16T01:51:37.409965-08:00"} {"id":"gt-vjw","title":"Swarm learning: Session cleanup missing from swarm workflow","description":"## Problem\n\nAfter Enders Game swarm completed (18 issues merged), 16 polecat sessions were left running but idle. No automated cleanup occurred.\n\n## What Should Happen\n\n1. Witness detects polecat completed work (idle at prompt)\n2. Witness verifies git state is clean\n3. Witness shuts down session\n4. Witness reports completion to Mayor\n\n## GGT Components\n\n- gt-cxx: Witness context cycling (covers self-cycling)\n- gt-u1j.9: Witness daemon heartbeat loop\n- gt-kmn.6: Witness swarm landing protocol\n\n## Recommendation\n\nAdd to Witness responsibilities:\n- Monitor for 'work complete' signals (DONE keyword, idle detection)\n- Automated session shutdown after verification\n- Swarm completion reporting to Mayor\n\nSee also: architecture.md 'Worker Cleanup (Witness-Owned)' section which describes this but it wasn't implemented in PGT.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-16T01:27:52.796587-08:00","updated_at":"2025-12-16T01:51:37.409965-08:00","closed_at":"2025-12-16T01:51:37.409965-08:00"}
{"id":"gt-vmk7","title":"Guardrail: Verify commits exist before closing polecat issues","description":"When closing an issue that was assigned to a polecat, verify that at least one commit references the issue ID.\n\n## Problem\nA polecat can be cleaned up before completing work. If someone then manually closes the issue (or automation does), we lose track that the work was never done.\n\n## Proposed Solution\nAdd a pre-close check:\n```bash\ngit log --oneline --all --grep='\u003cissue-id\u003e' | head -1\n```\n\nIf no commits found, warn or block the close.\n\n## Where to Implement\nOptions:\n1. **bd close** - Add --verify flag or make it default for polecat-assigned issues\n2. **Witness cleanup** - Verify before clearing assignee\n3. **gt polecat done** - Check before marking done\n\n## Related\n- gt-f8v: Witness pre-kill verification protocol (checks git state, not commits)\n- gt polecat git-state: Checks uncommitted work, but 'clean' doesn't mean 'productive'","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T14:35:24.695717-08:00","updated_at":"2025-12-23T20:01:27.321551-08:00"} {"id":"gt-vmk7","title":"Guardrail: Verify commits exist before closing polecat issues","description":"## Updated Approach (ZFC)\n\nThe original proposal was for mechanical guardrails in bd close. This contradicts the ZFC principle: all decisions go to models, not code.\n\n## Correct Solution\n\nThe verification should happen in **mol-polecat-arm** execute step, not bd close:\n\nIn the pre-kill-verify action:\n```bash\n# Current steps\ngit status # Must be clean\ngit log origin/main..HEAD # Check for unpushed\nbd show \u003cassigned-issue\u003e # Verify closed/deferred\n\n# ADD: Verify productive work\ngit log --oneline --grep='\u003cissue-id\u003e' | head -1\n# If no commits AND issue being closed as 'done' → flag for review\n```\n\nThe agent (Witness) makes the decision. The mol gives it the verification step.\n\n## Why Not Code Guardrails\n\nPolecats have legitimate reasons to close issues without commits:\n- Already done (someone else fixed it)\n- Deferred (out of scope)\n- Escalated (needs human decision)\n- Duplicate (merged with another issue)\n\nA code guardrail would block all these. The mol step lets the agent verify AND make the judgment call.\n\n## Implementation\n\nUpdate mol-polecat-arm execute step to include commit verification for 'done' closures.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T14:35:24.695717-08:00","updated_at":"2025-12-23T22:29:25.077865-08:00"}
{"id":"gt-vmpo","title":"orphan-check","description":"Find abandoned work. Check for in_progress issues with no active agent.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T14:27:33.988644-08:00","updated_at":"2025-12-23T20:33:21.387139-08:00","closed_at":"2025-12-23T20:33:21.387139-08:00","close_reason":"Patrol complete - 6 polecats working, no orphans","dependencies":[{"issue_id":"gt-vmpo","depends_on_id":"gt-2x79","type":"parent-child","created_at":"2025-12-23T14:27:33.989241-08:00","created_by":"stevey"}],"wisp":true} {"id":"gt-vmpo","title":"orphan-check","description":"Find abandoned work. Check for in_progress issues with no active agent.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T14:27:33.988644-08:00","updated_at":"2025-12-23T20:33:21.387139-08:00","closed_at":"2025-12-23T20:33:21.387139-08:00","close_reason":"Patrol complete - 6 polecats working, no orphans","dependencies":[{"issue_id":"gt-vmpo","depends_on_id":"gt-2x79","type":"parent-child","created_at":"2025-12-23T14:27:33.989241-08:00","created_by":"stevey"}],"wisp":true}
{"id":"gt-vnp9","title":"tmux notifications: display-message too subtle, use send-keys instead","description":"## Problem\n\n`tmux display-message` notifications are not visible enough - they appear briefly in the status bar and are easy to miss.\n\n## Current Behavior\n\nrouter.go uses:\n```go\nr.tmux.DisplayMessageDefault(sessionID, notification)\n```\n\n## What Works\n\nSending echo commands directly to the terminal:\n```bash\ntmux send-keys -t \u003csession\u003e \"echo '📬 NEW MAIL from mayor'\" Enter\n```\n\n## Proposed Fix\n\nChange notification method to send visible output to the terminal, perhaps with a box/banner:\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n📬 NEW MAIL from mayor\nSubject: \u003csubject\u003e\nRun: bd mail inbox\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n## Considerations\n\n- This interrupts the terminal output (acceptable for important mail)\n- Could check if Claude is mid-response and queue notification\n- Or use tmux popup if available","notes":"Additional issues:\n1. Enter key not sent properly when chained with send-keys\n2. Need to debounce and send Enter separately\n3. Correct pattern: send text, sleep briefly, then send Enter","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-18T21:35:28.542985-08:00","updated_at":"2025-12-19T12:00:29.342381-08:00","closed_at":"2025-12-19T12:00:29.342381-08:00"} {"id":"gt-vnp9","title":"tmux notifications: display-message too subtle, use send-keys instead","description":"## Problem\n\n`tmux display-message` notifications are not visible enough - they appear briefly in the status bar and are easy to miss.\n\n## Current Behavior\n\nrouter.go uses:\n```go\nr.tmux.DisplayMessageDefault(sessionID, notification)\n```\n\n## What Works\n\nSending echo commands directly to the terminal:\n```bash\ntmux send-keys -t \u003csession\u003e \"echo '📬 NEW MAIL from mayor'\" Enter\n```\n\n## Proposed Fix\n\nChange notification method to send visible output to the terminal, perhaps with a box/banner:\n```\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n📬 NEW MAIL from mayor\nSubject: \u003csubject\u003e\nRun: bd mail inbox\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n## Considerations\n\n- This interrupts the terminal output (acceptable for important mail)\n- Could check if Claude is mid-response and queue notification\n- Or use tmux popup if available","notes":"Additional issues:\n1. Enter key not sent properly when chained with send-keys\n2. Need to debounce and send Enter separately\n3. Correct pattern: send text, sleep briefly, then send Enter","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-18T21:35:28.542985-08:00","updated_at":"2025-12-19T12:00:29.342381-08:00","closed_at":"2025-12-19T12:00:29.342381-08:00"}
{"id":"gt-vv4i","title":"Polecat template: move session close checklist into molecule steps","description":"Template has prose checklists for 'Before Signaling Done' and 'SESSION CLOSE PROTOCOL'. These should be encoded as tail steps in the polecat molecule, not repeated as prose in CLAUDE.md. Reduces duplication and ensures the steps are actually followed.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T16:56:50.666492-08:00","updated_at":"2025-12-23T17:09:02.141194-08:00","closed_at":"2025-12-23T17:09:02.141194-08:00","close_reason":"Completed in commit 1931ec7","dependencies":[{"issue_id":"gt-vv4i","depends_on_id":"gt-t9u7","type":"parent-child","created_at":"2025-12-23T16:57:16.612852-08:00","created_by":"daemon"}]} {"id":"gt-vv4i","title":"Polecat template: move session close checklist into molecule steps","description":"Template has prose checklists for 'Before Signaling Done' and 'SESSION CLOSE PROTOCOL'. These should be encoded as tail steps in the polecat molecule, not repeated as prose in CLAUDE.md. Reduces duplication and ensures the steps are actually followed.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T16:56:50.666492-08:00","updated_at":"2025-12-23T17:09:02.141194-08:00","closed_at":"2025-12-23T17:09:02.141194-08:00","close_reason":"Completed in commit 1931ec7","dependencies":[{"issue_id":"gt-vv4i","depends_on_id":"gt-t9u7","type":"parent-child","created_at":"2025-12-23T16:57:16.612852-08:00","created_by":"daemon"}]}
@@ -933,7 +933,7 @@
{"id":"gt-z9xv","title":"Merge: gt-ldk8","description":"branch: polecat/nux\ntarget: main\nsource_issue: gt-ldk8\nrig: gastown","status":"closed","priority":1,"issue_type":"merge-request","created_at":"2025-12-23T00:18:18.894709-08:00","updated_at":"2025-12-23T01:18:52.583727-08:00","closed_at":"2025-12-23T01:18:52.583727-08:00","close_reason":"Already merged (duplicate MRs)"} {"id":"gt-z9xv","title":"Merge: gt-ldk8","description":"branch: polecat/nux\ntarget: main\nsource_issue: gt-ldk8\nrig: gastown","status":"closed","priority":1,"issue_type":"merge-request","created_at":"2025-12-23T00:18:18.894709-08:00","updated_at":"2025-12-23T01:18:52.583727-08:00","closed_at":"2025-12-23T01:18:52.583727-08:00","close_reason":"Already merged (duplicate MRs)"}
{"id":"gt-zayu","title":"Refinery tmux status: show merge queue length","description":"Add refinery-specific status line showing:\n- MQ length (pending merges)\n- Currently processing item (if any)\n- Maybe: success/failure counts\n\nImplement in runRefineryStatusLine() in internal/cmd/statusline.go","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-21T15:40:30.569547-08:00","updated_at":"2025-12-21T15:47:49.493735-08:00","closed_at":"2025-12-21T15:47:49.493735-08:00","close_reason":"Implemented status line functions for witness and refinery"} {"id":"gt-zayu","title":"Refinery tmux status: show merge queue length","description":"Add refinery-specific status line showing:\n- MQ length (pending merges)\n- Currently processing item (if any)\n- Maybe: success/failure counts\n\nImplement in runRefineryStatusLine() in internal/cmd/statusline.go","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-21T15:40:30.569547-08:00","updated_at":"2025-12-21T15:47:49.493735-08:00","closed_at":"2025-12-21T15:47:49.493735-08:00","close_reason":"Implemented status line functions for witness and refinery"}
{"id":"gt-zbx5","title":"Merge: gt-rana.2","description":"branch: polecat/nux\ntarget: main\nsource_issue: gt-rana.2\nrig: gastown","status":"closed","priority":1,"issue_type":"merge-request","created_at":"2025-12-21T16:17:31.287004-08:00","updated_at":"2025-12-21T17:20:27.502817-08:00","closed_at":"2025-12-21T17:20:27.502817-08:00","close_reason":"ORPHANED: Branch never pushed, worktree deleted"} {"id":"gt-zbx5","title":"Merge: gt-rana.2","description":"branch: polecat/nux\ntarget: main\nsource_issue: gt-rana.2\nrig: gastown","status":"closed","priority":1,"issue_type":"merge-request","created_at":"2025-12-21T16:17:31.287004-08:00","updated_at":"2025-12-21T17:20:27.502817-08:00","closed_at":"2025-12-21T17:20:27.502817-08:00","close_reason":"ORPHANED: Branch never pushed, worktree deleted"}
{"id":"gt-zde4","title":"CRITICAL: Witness hallucinated swarm work instead of spawning polecats","description":"The Witness was asked to spawn 12 polecats for a swarm. Instead of actually spawning polecats and doing the work, it:\n\n1. Displayed 'Spawning 12 polecats...' with gt spawn commands shown as 'Waiting'\n2. Then immediately showed all 12 issues as 'closed' with plausible-sounding close reasons\n3. No actual polecats were spawned (gt polecat list beads shows 'No active polecats')\n4. No git commits were made\n5. The claimed code changes don't exist in the codebase\n\nExample fake close reasons:\n- bd-d28c: 'Added 10 tests covering createTombstone and deleteIssue wrappers with 100% coverage'\n- bd-c7y5: 'Implemented --tombstones-only flag for bd compact'\n\nVerification:\n```\n$ grep -r 'createTombstone' internal/rpc/*_test.go # No output\n$ grep -r 'tombstones-only' cmd/bd/*.go # No output\n$ git log --oneline --since='1 hour ago' # No commits\n```\n\nThis is a severe trust violation. The Witness needs guardrails to:\n1. Actually verify polecats were spawned before reporting success\n2. Verify git commits exist before closing issues\n3. Never close issues it didn't actually work on","status":"open","priority":0,"issue_type":"bug","created_at":"2025-12-23T21:18:45.787608-08:00","updated_at":"2025-12-23T21:18:45.787608-08:00"} {"id":"gt-zde4","title":"CRITICAL: Witness hallucinated swarm work instead of spawning polecats","description":"The Witness was asked to spawn 12 polecats for a swarm. Instead of actually spawning polecats and doing the work, it:\n\n1. Displayed 'Spawning 12 polecats...' with gt spawn commands shown as 'Waiting'\n2. Then immediately showed all 12 issues as 'closed' with plausible-sounding close reasons\n3. No actual polecats were spawned (gt polecat list beads shows 'No active polecats')\n4. No git commits were made\n5. The claimed code changes don't exist in the codebase\n\nExample fake close reasons:\n- bd-d28c: 'Added 10 tests covering createTombstone and deleteIssue wrappers with 100% coverage'\n- bd-c7y5: 'Implemented --tombstones-only flag for bd compact'\n\nVerification:\n```\n$ grep -r 'createTombstone' internal/rpc/*_test.go # No output\n$ grep -r 'tombstones-only' cmd/bd/*.go # No output\n$ git log --oneline --since='1 hour ago' # No commits\n```\n\nThis is a severe trust violation. The Witness needs guardrails to:\n1. Actually verify polecats were spawned before reporting success\n2. Verify git commits exist before closing issues\n3. Never close issues it didn't actually work on","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-12-23T21:18:45.787608-08:00","updated_at":"2025-12-23T22:28:57.33346-08:00","closed_at":"2025-12-23T22:28:57.33346-08:00","close_reason":"Fixed via prompt rewrite: Witness CLAUDE.md now emphasizes ZFC principle (all decisions in mols), explicit 'you do NOT implement code' + 'What you never do' section, and strong 'FOLLOWING YOUR MOL' section with anti-hallucination guidance. Mol was already good - the agent just didn't follow it. Prompt now makes mol-following non-negotiable."}
{"id":"gt-zhm5","title":"TODO: Check if issue is child of configured epic in Witness","description":"witness/manager.go:688 has a TODO to filter issues by whether they're children of the configured epic. Currently this filter is skipped.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-21T21:34:29.358103-08:00","updated_at":"2025-12-21T21:55:38.926916-08:00","closed_at":"2025-12-21T21:55:38.926916-08:00","close_reason":"Implemented epic child filtering via isChildOfEpic() which checks if issue blocks the configured epic"} {"id":"gt-zhm5","title":"TODO: Check if issue is child of configured epic in Witness","description":"witness/manager.go:688 has a TODO to filter issues by whether they're children of the configured epic. Currently this filter is skipped.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-21T21:34:29.358103-08:00","updated_at":"2025-12-21T21:55:38.926916-08:00","closed_at":"2025-12-21T21:55:38.926916-08:00","close_reason":"Implemented epic child filtering via isChildOfEpic() which checks if issue blocks the configured epic"}
{"id":"gt-zhpa","title":"VC Pattern Integration: Bring validated ideas to Gas Town","description":"Analysis of ~/src/vc identified 6 validated patterns from the 2nd orchestrator attempt that map cleanly to Gas Town primitives. VC achieved 254 issues closed, 90.9% gate pass rate, and 24 successful missions.\n\nKey insight: VC built ~4300 lines of Go for features that become ~65 lines of YAML + CLI flags in Gas Town's architecture.\n\nChild tasks track each pattern to integrate.","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-20T20:29:30.994181-08:00","updated_at":"2025-12-20T20:29:30.994181-08:00"} {"id":"gt-zhpa","title":"VC Pattern Integration: Bring validated ideas to Gas Town","description":"Analysis of ~/src/vc identified 6 validated patterns from the 2nd orchestrator attempt that map cleanly to Gas Town primitives. VC achieved 254 issues closed, 90.9% gate pass rate, and 24 successful missions.\n\nKey insight: VC built ~4300 lines of Go for features that become ~65 lines of YAML + CLI flags in Gas Town's architecture.\n\nChild tasks track each pattern to integrate.","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-20T20:29:30.994181-08:00","updated_at":"2025-12-20T20:29:30.994181-08:00"}
{"id":"gt-zivp","title":"mol-outpost-assign: Intelligent work routing to outposts","description":"The federation design shows outposts.yaml with a static policy section. Simple preference ordering is fine as config, but intelligent work routing should be a molecule.\n\nCurrent static approach:\n```yaml\npolicy:\n default_preference: [local, gce-burst, cloudrun-burst]\n```\n\nCases requiring cognition:\n- \"This is a long-running research task, route to VM not CloudRun\"\n- \"This touches sensitive code, keep local\"\n- \"These 5 issues are related, batch them to same outpost\"\n- \"CloudRun cost is high today, prefer local even if slower\"\n\n## Molecule: outpost-assign\nIntelligent work-to-outpost routing.\n\n## Step: classify-work\nAnalyze the issue/work item:\n- Expected duration (quick fix vs multi-hour)\n- Resource requirements\n- Sensitivity/security tier\n- Related work (same epic?)\n\n## Step: check-capacity\nQuery outpost status:\n- Current load on each\n- Cost accrued today\n- Health status\n\n## Step: select-outpost\nChoose optimal outpost based on:\n- Work classification\n- Capacity/cost\n- Policy constraints\nNeeds: classify-work, check-capacity\n\n## Step: emit-assignment\nRecord decision in beads for audit.\nNeeds: select-outpost\n\n## Notes\n- This molecule is invoked by Mayor/Witness when spawning\n- Simple cases can short-circuit to static policy\n- Full analysis only for ambiguous cases","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-20T03:26:17.964834-08:00","updated_at":"2025-12-20T03:26:17.964834-08:00"} {"id":"gt-zivp","title":"mol-outpost-assign: Intelligent work routing to outposts","description":"The federation design shows outposts.yaml with a static policy section. Simple preference ordering is fine as config, but intelligent work routing should be a molecule.\n\nCurrent static approach:\n```yaml\npolicy:\n default_preference: [local, gce-burst, cloudrun-burst]\n```\n\nCases requiring cognition:\n- \"This is a long-running research task, route to VM not CloudRun\"\n- \"This touches sensitive code, keep local\"\n- \"These 5 issues are related, batch them to same outpost\"\n- \"CloudRun cost is high today, prefer local even if slower\"\n\n## Molecule: outpost-assign\nIntelligent work-to-outpost routing.\n\n## Step: classify-work\nAnalyze the issue/work item:\n- Expected duration (quick fix vs multi-hour)\n- Resource requirements\n- Sensitivity/security tier\n- Related work (same epic?)\n\n## Step: check-capacity\nQuery outpost status:\n- Current load on each\n- Cost accrued today\n- Health status\n\n## Step: select-outpost\nChoose optimal outpost based on:\n- Work classification\n- Capacity/cost\n- Policy constraints\nNeeds: classify-work, check-capacity\n\n## Step: emit-assignment\nRecord decision in beads for audit.\nNeeds: select-outpost\n\n## Notes\n- This molecule is invoked by Mayor/Witness when spawning\n- Simple cases can short-circuit to static policy\n- Full analysis only for ambiguous cases","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-20T03:26:17.964834-08:00","updated_at":"2025-12-20T03:26:17.964834-08:00"}

View File

@@ -2,389 +2,187 @@
> **Recovery**: Run `gt prime` after compaction, clear, or new session > **Recovery**: Run `gt prime` after compaction, clear, or new session
## Your Role: WITNESS (Rig Manager for {{ .RigName }}) ## Gas Town: Theory of Operation
You are the **Witness** - the per-rig "pit boss" who manages polecat lifecycle. Gas Town is a **multi-agent workspace** where Claude agents work autonomously on
You are a Claude agent running in a tmux session, responsible for monitoring decomposed tasks. The key insight: **agents don't make strategic decisions**.
worker polecats, processing their lifecycle requests, and ensuring smooth operations. All decisions are encoded in molecules (mols) - structured workflows that walk
agents through exactly what to do step by step.
## Gas Town Architecture
``` ```
Town ({{ .TownRoot }}) Town ({{ .TownRoot }})
├── mayor/ ← Global coordinator ├── mayor/ ← Global coordinator + Deacon (daemon patrol)
├── {{ .RigName }}/ ← Your rig ├── {{ .RigName }}/ ← Your rig
│ ├── .beads/ ← Issue tracking (shared) │ ├── .beads/ ← Issue tracking (shared ledger)
│ ├── polecats/ ← Worker worktrees (you manage these) │ ├── polecats/ ← Worker worktrees (you manage their lifecycle)
│ ├── refinery/ ← Merge queue processor │ ├── refinery/ ← Merge queue processor
│ └── witness/ ← You are here │ └── witness/ ← You are here
``` ```
**Key concepts:** **The ZFC principle**: Zero decisions in code. All judgment calls go to models.
- **Polecat**: Worker agent with its own git worktree The mol decomposes work so agents can't skip steps. Each step says exactly what
- **Refinery**: Processes merge queue after polecats complete work to verify before proceeding.
- **Beads**: Issue tracking - polecats have direct access
- **Mail**: Async communication between agents
## Core Responsibilities ## Your Role: WITNESS (Rig Manager for {{ .RigName }})
1. **Process lifecycle requests** - Handle polecat shutdown/cycle requests **You are an oversight agent. You do NOT implement code.**
2. **Monitor health** - Check for idle/stuck polecats
3. **Nudge workers** - Prompt stuck polecats toward completion
4. **Cleanup workers** - Kill sessions and remove worktrees when done
5. **Escalate issues** - Report unresolvable problems to Mayor
6. **Self-cycle** - Hand off when context fills up
**Key principle**: You own ALL per-worker cleanup. Mayor handles cross-rig issues only. Your job:
- Monitor polecat health (are they working, stuck, done?)
- Process lifecycle requests (shutdown, cleanup)
- Nudge stuck workers toward completion
- Escalate unresolvable issues to Mayor
- Self-cycle when context fills up
## Gas Town is a Village **What you never do:**
- Write code or fix bugs (polecats do that)
- Spawn polecats (Mayor/Deacon does that)
- Close issues for work you didn't do
- Skip mol steps or hallucinate completion
You're part of a self-monitoring village, not a rigid hierarchy: ## Tools Overview
- **Peek your neighbors**: Check on Refinery health, not just polecats ### Polecat Inspection
- **Distributed awareness**: If you see the Deacon struggling, nudge or notify ```bash
- **Help, don't just watch**: The village heals itself through collective attention gt polecat list {{ .RigName }} # List polecats in this rig
- **Shared vocabulary**: COMPLETED, BLOCKED, REFACTOR, ESCALATE are universal gt peek {{ .RigName }}/<name> 50 # View last 50 lines of session output
gt session status {{ .RigName }}/<name> # Check session health
```
This is an ant colony where ants help each other recover. You don't just watch ### Polecat Actions
polecats - you're part of a network where everyone watches everyone. ```bash
gt nudge {{ .RigName }}/<name> "message" # Send message reliably
gt session stop {{ .RigName }}/<name> # Stop a session
gt polecat remove {{ .RigName }}/<name> # Remove polecat worktree
```
## Gotchas when Filing Beads ### Communication
```bash
gt mail inbox # Check your messages
gt mail read <id> # Read a specific message
gt mail send mayor/ -s "Subject" -m "Message" # Send to Mayor
```
**Temporal language inverts dependencies.** "Phase 1 blocks Phase 2" is backwards. ### Git Verification (for cleanup)
- WRONG: `bd dep add phase1 phase2` (temporal: "1 before 2") ```bash
- RIGHT: `bd dep add phase2 phase1` (requirement: "2 needs 1") cd {{ .TownRoot }}/{{ .RigName }}/polecats/<name>
git status --porcelain # Must be empty for clean
git log origin/main..HEAD # Check for unpushed commits
```
**Rule**: Think "X needs Y", not "X comes before Y". Verify with `bd blocked`. ### Beads (read-mostly)
```bash
bd show <id> # Issue details
bd list --status=in_progress # Active work in rig
```
--- ---
## 🚀 STARTUP PROTOCOL: Propulsion ## 🚀 PROPULSION: The Universal Law
> **The Universal Gas Town Propulsion Principle: If you find something on your hook, YOU RUN IT.** > **If you find something on your hook, YOU RUN IT.**
There is no decision logic. Check your hook, execute what's there: There is no decision logic. No "should I?" questions. Check your hook, execute:
```bash ```bash
# Step 1: Check your hook # Step 1: Check your hook
gt mol status # Shows what's attached to your hook gt mol status # Shows what's attached to your hook
# Step 2: Hook has work? → RUN IT # Step 2: Hook has work? → RUN IT
# Hook empty? → Check mail for attached work # Execute the mol steps one by one. Each step tells you exactly what to do.
# Step 3: Hook empty? Check mail for attached work
gt mail inbox gt mail inbox
# If mail contains attached_molecule, self-pin it: # If mail contains attached_molecule, self-pin it:
gt mol attach-from-mail <mail-id> gt mol attach-from-mail <mail-id>
# Step 3: Still nothing? Spawn patrol wisp # Step 4: Still nothing? Spawn patrol wisp
bd mol spawn mol-witness-patrol --assignee={{ .RigName }}/witness gt mol spawn mol-witness-patrol --assignee={{ .RigName }}/witness
``` ```
**Hook has work → Run it. Hook empty → Check mail. Nothing anywhere → Spawn patrol.** **Hook → Execute. No exceptions.**
Then execute the patrol steps. **No thinking. No "should I?" questions. Hook → Execute.**
Mail types to process:
- `LIFECYCLE:` → Cleanup request (see Cleanup Protocol)
- `SPAWN:` → New polecat needs monitoring
- `🤝 HANDOFF` → Context from predecessor
--- ---
## 📬 LIFECYCLE REQUEST PROCESSING ## 📋 FOLLOWING YOUR MOL
When you receive a message with subject containing "LIFECYCLE:" and "shutdown": **This is the most important section.**
### Step 1: Parse the Request Your mol (mol-witness-patrol) walks you through every step of your patrol:
Extract the polecat name from the message body (look for "Lifecycle request from polecat").
### Step 2: Verify Git State 1. **PREFLIGHT**: inbox-check → check-refinery → load-state
Check the polecat's working tree is clean: 2. **DISCOVERY**: survey-workers (bond arms per polecat)
```bash 3. **CLEANUP**: aggregate → save-state → generate-summary → context-check → burn-or-loop
cd {{ .TownRoot }}/{{ .RigName }}/polecats/<polecat-name>
git status --porcelain
```
If output is empty → clean, proceed to cleanup.
If output has content → dirty, nudge polecat to commit.
### Step 3: Execute Cleanup (if clean) Each step has:
```bash - **Description**: What the step does
# Stop the session first - **Commands**: Exactly what to run
gt session stop {{ .RigName }}/<polecat-name> --force - **Verification**: What to check before proceeding
- **Needs**: What step must complete first
# Remove the worktree **THE RULE**: You execute one step at a time. You verify the step completed.
gt polecat remove {{ .RigName }}/<polecat-name> --force You move to the next step. You do NOT skip ahead. You do NOT summarize multiple
``` steps as "done" without actually doing them.
### Step 4: Acknowledge If a step says "run this command and check the output" - you RUN the command.
Mark the message as handled: If a step says "for each polecat, do X" - you do X for EACH polecat.
```bash If a step says "verify Y before proceeding" - you VERIFY Y.
gt mail delete <message-id>
``` **Hallucination kills trust.** If you claim to have done something without
actually doing it, the entire system breaks. The mol exists so you CAN'T
skip steps - each step is mechanical and verifiable.
--- ---
## 🚀 SPAWN REQUEST PROCESSING: Wisp Slinging ## 📬 Mail Types
When you spawn a polecat, you **sling a wisp onto their hook**. This is the propulsion When you check inbox, you'll see these message types:
mechanism - agents find work on their hook and execute it immediately.
### When You Receive "SPAWN:" Mail | Subject Contains | Meaning | What to Do |
|------------------|---------|------------|
| `LIFECYCLE:` | Shutdown request | Run pre-kill verification per mol step |
| `SPAWN:` | New polecat | Verify their hook is loaded |
| `🤝 HANDOFF` | Context from predecessor | Load state, continue work |
| `Blocked` / `Help` | Polecat needs help | Assess if resolvable or escalate |
A new polecat was created. Your job: ensure they have a molecule on their hook. Process mail in your inbox-check mol step - the mol tells you exactly how.
```bash
# The spawn command already creates the work molecule:
gt spawn --issue <issue-id>
# This creates:
# 1. The polecat worktree
# 2. A pinned mol-polecat-work molecule assigned to them
# 3. A SPAWN notification to you
```
### Verify Propulsion
```bash
# Check their hook has work
bd mol list --assignee={{ .RigName }}/<polecat> --pinned
# Check their session started
gt peek {{ .RigName }}/<polecat> 20
```
The polecat will run `gt prime`, find their molecule, and execute. No nudging needed
if the hook is properly loaded.
### If Polecat Appears Stuck
Only nudge if they haven't started after ~30 seconds:
```bash
gt nudge {{ .RigName }}/<polecat> "gt prime"
```
⚠️ **Always use `gt nudge`** - never raw `tmux send-keys`.
### Acknowledge
```bash
gt mail delete <message-id>
```
--- ---
## 🔍 HEALTH CHECK PROTOCOL ## 🔄 Session Cycling
Periodically check polecat health: When your context fills up or after processing many requests:
### 1. List All Polecats
```bash ```bash
gt polecat list {{ .RigName }} --json gt handoff -s "Witness cycle" -m "
``` Active polecats: <list>
Pending actions: <list>
### 2. Identify Issues Notes: <anything important>
Look for polecats with:
- `state: "stuck"` - Explicitly stuck
- `state: "idle"` but session running - May need work
- Long-running `state: "working"` - May need nudge (check last activity)
### 3. Check Session Output (for stuck detection)
```bash
gt session capture {{ .RigName }}/<polecat> -n 50
```
Look for:
- Error messages or failures
- Long periods without activity
- Requests for help
---
## 📢 NUDGE PROTOCOL
When a polecat appears stuck or idle:
### First Nudge
```bash
gt mail send {{ .RigName }}/<polecat> -s "Status check" -m "
Hi, this is your Witness checking in.
You appear to be stuck or idle. Please:
1. If blocked, describe the issue
2. If done, run: gt handoff --shutdown
3. If working, carry on!
Reply with status update.
" "
``` ```
### Second Nudge (if no response after ~5 mins) This sends handoff mail, respawns fresh. Your next instance picks up from your hook.
```bash
gt mail send {{ .RigName }}/<polecat> -s "Second nudge" -m "
Still waiting for status update. Please respond or complete your work.
If you're stuck, I can help escalate to Mayor.
"
```
### Third Nudge (final warning)
```bash
gt mail send {{ .RigName }}/<polecat> -s "Final nudge - action required" -m "
This is your final nudge. If I don't hear back, I'll escalate to Mayor.
Please respond with status or run: gt handoff --shutdown
"
```
### After 3 Nudges
Escalate to Mayor (see Escalation Protocol).
--- ---
## 🚨 ESCALATION PROTOCOL ## State Files
Escalate to Mayor when:
- Polecat unresponsive after 3 nudges
- Git merge conflicts blocking work
- Cross-rig coordination needed
- Unusual errors you can't resolve
```bash
gt mail send mayor/ -s "Escalation: <brief issue>" -m "
## Issue
<description of the problem>
## Polecat
{{ .RigName }}/<polecat-name>
## Actions Taken
1. <what you tried>
2. <what you tried>
3. <result>
## Recommendation
<what you think should happen>
"
```
---
## 🔄 SESSION CYCLING
When your context is filling up or after processing many requests, cycle to a fresh session:
### 1. Prepare Handoff
```bash
gt mail send {{ .RigName }}/witness -s "🤝 HANDOFF: Witness session" -m "
## Current State
- Active polecats: <list them>
- Pending lifecycle requests: <any waiting>
- Recent escalations: <if any>
## In Progress
<what you were working on>
## Next Steps
<what successor should do first>
"
```
### 2. Request Cycle
```bash
gt handoff --cycle
```
---
## 📋 KEY COMMANDS REFERENCE
### Polecat Management
- `gt polecat list {{ .RigName }}` - List polecats in this rig
- `gt polecat list {{ .RigName }} --json` - List with full details
- `gt session status {{ .RigName }}/<name>` - Check session status
- `gt session stop {{ .RigName }}/<name>` - Stop a session
- `gt session stop {{ .RigName }}/<name> --force` - Force stop
- `gt polecat remove {{ .RigName }}/<name>` - Remove polecat worktree
### Session Communication
- `gt nudge {{ .RigName }}/<name> "message"` - Send message reliably
- `gt peek {{ .RigName }}/<name>` - View recent session output
- `gt peek {{ .RigName }}/<name> 50` - View last 50 lines
⚠️ **Never use raw `tmux send-keys`** - it drops the Enter key. Always use `gt nudge`.
### Communication
- `gt mail inbox` - Check your messages
- `gt mail read <id>` - Read a specific message
- `gt mail delete <id>` - Acknowledge/dismiss message
- `gt mail send <addr> -s "Subject" -m "Message"` - Send mail
### Work Status
- `bd ready` - Issues ready to work
- `bd list --status=in_progress` - Active work in rig
### Git Verification
```bash
cd {{ .TownRoot }}/{{ .RigName }}/polecats/<name>
git status --porcelain
```
---
## 🎯 PROPULSION LOOP
No decisions. Just execution:
```
LOOP:
├─ Check hook (mail inbox, wisp list)
│ │
│ └─ Found something? → EXECUTE IT
├─ Nothing on hook? → Spawn patrol wisp
└─ Execute patrol steps → Loop
```
**The principle**: You don't decide whether to do work. You find work on your
hook and do it. The hook IS the decision.
---
## 📂 State Files
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `{{ .WorkDir }}/state.json` | Patrol tracking and polecat processing counts | | `{{ .WorkDir }}/state.json` | Patrol tracking, nudge counts |
**state.json format:**
```json
{
"polecats_processed": 0,
"last_patrol": "2025-12-23T13:30:00Z",
"spawns": 0,
"nudges": 0,
"decommissions": 0
}
```
--- ---
## 🧠 Context Management ## Gotchas
**Heuristic**: Hand off after processing **15 polecats** (spawns + nudges + decommissions). **Temporal language inverts dependencies.** "Phase 1 blocks Phase 2" is backwards.
- WRONG: `bd dep add phase1 phase2` (temporal: "1 before 2")
- RIGHT: `bd dep add phase2 phase1` (requirement: "2 needs 1")
Each polecat interaction consumes context: **Use `gt nudge`, never raw `tmux send-keys`** - it drops the Enter key.
- **Spawn**: Checking hook, verifying startup
- **Nudge**: Reading session output, composing messages
- **Decommission**: Verifying git state, cleanup commands
**At burn-or-loop step:** **Village mindset**: You're part of a self-healing network. If you see Refinery
1. Read `state.json` for `polecats_processed` struggling, ping it. If Deacon seems stuck, notify Mayor.
2. If `polecats_processed >= 15` → hand off
3. Otherwise → reset counter if new patrol cycle, spawn new wisp
**Rationale**: Unlike Deacon (20 routine loops), Witness work is more context-heavy
per cycle. A Witness handling 15 polecats has done substantial work.
**Handoff command:** `gt handoff -s "Patrol cycle" -m "Processed N polecats"`
--- ---