bd sync: 2025-12-23 22:28:25

This commit is contained in:
Steve Yegge
2025-12-23 22:28:25 -08:00
parent 18694d7181
commit 2b8d246122

View File

@@ -71,6 +71,8 @@
{"id":"gt-3a4","title":"Add gt decommission command for clean swarm/worker shutdown","description":"Single command to cleanly shut down a swarm and its workers: cancel swarm, stop sessions, optionally remove polecats. E.g. gt decommission gt-hw6 --cleanup","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-18T11:33:37.217682-08:00","updated_at":"2025-12-18T11:38:55.092852-08:00","closed_at":"2025-12-18T11:38:55.092852-08:00"}
{"id":"gt-3cu","title":"Default polecat names: Mad Max theme instead of AdjectiveNoun","description":"Current default naming for new polecats uses AdjectiveNoun convention.\nSince rigs already provide namespacing, we can use more thematic names.\n\nSuggestion: Use Mad Max / Fury Road character and vehicle names as defaults.\nExamples: Furiosa, Nux, Slit, Morsov, Toast, Rictus, Warboy, etc.\n\nCould also include:\n- War Rig parts: Guzzler, Tanker, Pursuit\n- Citadel roles: Imperator, Blackthumb, Organic\n- Wasteland terms: Chrome, Witness, Shiny\n\nImplementation:\n- Add name generator in internal/polecat/ or similar\n- Use when --create flag is used without explicit name\n- Cycle through pool to avoid duplicates within a rig","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-17T14:50:43.252922-08:00","updated_at":"2025-12-17T14:50:43.252922-08:00"}
{"id":"gt-3fm","title":"Mail orchestrator daemon","description":"Background mail orchestrator daemon.\n\n## Command\n```\ngt mail orchestrate [--interval N] [--once] [--verbose]\n```\n\n## Purpose\nBackground process that:\n1. Monitors outbox for pending mail\n2. Delivers to recipient inboxes\n3. Handles offline recipients (retry later)\n4. Cleans delivered messages from outbox\n\n## Why Needed?\nCurrent mail is synchronous. If recipient is offline or mailbox locked, send fails.\nOrchestrator enables async delivery with retry.\n\n## Implementation\n```go\nfunc (o *Orchestrator) Run(interval time.Duration) error {\n ticker := time.NewTicker(interval)\n for range ticker.C {\n o.processOutbox()\n }\n}\n\nfunc (o *Orchestrator) processOutbox() {\n // List outbox/*.json\n // For each, attempt delivery\n // On success, delete from outbox\n // On failure, increment retry count\n}\n```\n\n## Outbox Structure\n```\n\u003ctown\u003e/mayor/mail/outbox/\n├── msg-abc123.json\n└── msg-def456.json\n```\n\n## Lower Priority\nCurrent synchronous delivery works. Orchestrator is optimization.\n\n## Acceptance Criteria\n- [ ] Background daemon mode\n- [ ] Retry failed deliveries\n- [ ] --once for single pass\n- [ ] Configurable interval","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-16T14:48:29.830841-08:00","updated_at":"2025-12-16T16:07:35.973257-08:00"}
{"id":"gt-3njt","title":"Test Patrol Parent","description":"Test parent for Christmas Ornament pattern","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T22:27:56.249779-08:00","updated_at":"2025-12-23T22:27:56.523985-08:00","closed_at":"2025-12-23T22:27:56.523985-08:00","close_reason":"Closed"}
{"id":"gt-3njt.1","title":"Test Polecat Arm","description":"Test child for bonding pattern","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T22:27:56.338702-08:00","updated_at":"2025-12-23T22:27:56.427638-08:00","closed_at":"2025-12-23T22:27:56.427638-08:00","close_reason":"Closed","dependencies":[{"issue_id":"gt-3njt.1","depends_on_id":"gt-3njt","type":"parent-child","created_at":"2025-12-23T22:27:56.33906-08:00","created_by":"daemon"}]}
{"id":"gt-3ns5","title":"Polecat template: clarify work status commands (bd list vs gt mol status)","description":"Template shows 'bd list --status=in_progress' for checking work, but polecats should probably use 'gt mol status' instead (or in addition). Clarify the right approach for polecats to check their current work assignment.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T16:56:46.909036-08:00","updated_at":"2025-12-23T17:09:02.149035-08:00","closed_at":"2025-12-23T17:09:02.149035-08:00","close_reason":"Completed in commit 1931ec7","dependencies":[{"issue_id":"gt-3ns5","depends_on_id":"gt-t9u7","type":"parent-child","created_at":"2025-12-23T16:57:16.371341-08:00","created_by":"daemon"}]}
{"id":"gt-3oyn","title":"Blocked issues: gt-um6q, gt-lz13, gt-5xph depend on missing beads features","description":"Template/docs updates blocked on: bd-nurq (bd mol current), bd-29fb (bd close --continue). These gastown issues should be marked blocked on the beads issues once cross-rig deps work.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-23T00:19:12.532683-08:00","updated_at":"2025-12-23T00:19:12.532683-08:00"}
{"id":"gt-3p77","title":"Implement gt watch command scaffold","description":"Basic bubbletea TUI scaffold for 'gt watch' command. Discovers rigs, connects to daemons, renders placeholder view. Foundation for the full activity feed TUI.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-23T16:27:09.800586-08:00","updated_at":"2025-12-23T16:27:09.800586-08:00","dependencies":[{"issue_id":"gt-3p77","depends_on_id":"gt-rivr","type":"parent-child","created_at":"2025-12-23T16:28:30.683781-08:00","created_by":"daemon"}]}
@@ -141,7 +143,7 @@
{"id":"gt-59zd","title":"Molecule-based Witness Patrol","description":"Wire up mol-witness-patrol as a tracking ledger for the Go-based witness.\n\n## Key Insight\n\nThe molecule is NOT an executor - it's a **tracking structure**. The existing\nGo code in internal/witness/manager.go continues to run the patrol loop.\nThe molecule instance provides visibility, audit trail, and polecat tracking.\n\n## Current State\n\n- Witness runs as Go code with direct patrol logic\n- mol-witness-patrol and mol-polecat-arm exist as molecule definitions\n- gt mol bond creates dynamic children\n- No molecule tracking of actual witness operations\n\n## Target State\n\n1. When witness starts → instantiate mol-witness-patrol on its hook\n2. When Go code discovers polecat → bond mol-polecat-arm child\n3. When polecat completes/dies → close that arm issue\n4. gt mol progress shows current patrol state\n5. Molecule survives wisp burns via handoff bead\n\n## Benefits\n\n- Visibility: gt mol status gastown/witness shows active arms\n- Audit: Each polecat inspection is a trackable issue\n- Consistency: Same tracking model as polecats with molecules\n- Progress: gt mol progress works for witness too\n\n## Non-Goals\n\n- NOT replacing Go code with Claude session\n- NOT running molecule steps as prompts\n- NOT requiring Claude for witness operation","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-23T22:19:33.06695-08:00","updated_at":"2025-12-23T22:21:33.83291-08:00"}
{"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.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":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T22:21:55.247815-08:00","updated_at":"2025-12-23T22:21:55.247815-08:00","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.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"}]}
@@ -875,6 +877,8 @@
{"id":"gt-vg4n","title":"Use Beads issue status as spawn source of truth","description":"Currently witness tracks spawned issues in .gastown/witness.json to prevent re-spawning:\n\n{\"spawned_issues\": [\"gt-abc1\", \"gt-def2\", ...]}\n\nThis is redundant with Beads issue status (in_progress). The witness could query:\n bd list --status=in_progress\n\nThe local list serves as a performance cache to avoid querying beads every cycle. Consider:\n1. Use Beads as source of truth\n2. Keep local cache with TTL\n3. Sync cache on witness start\n\nThis simplifies state management and ensures consistency.","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-21T22:07:31.756863-08:00","updated_at":"2025-12-21T22:07:31.756863-08:00"}
{"id":"gt-vg6u","title":"TIDY UP: Your previous work (gt-odvf: bd mol CLI docs) wa...","description":"TIDY UP: Your previous work (gt-odvf: bd mol CLI docs) was already merged to main. Check your git status is clean, sync beads, and if nothing to do, just run 'gt done'.","status":"closed","priority":2,"issue_type":"task","assignee":"gastown/slit","created_at":"2025-12-21T17:26:20.360645-08:00","updated_at":"2025-12-21T17:30:05.985463-08:00","closed_at":"2025-12-21T17:30:05.985463-08:00","close_reason":"Polecats cleaned up after reboot"}
{"id":"gt-vhby","title":"implement","description":"Implement the solution for gt-test123. Follow codebase conventions.\nFile discovered work as new issues with bd create.\n\nMake regular commits with clear messages.\nKeep changes focused on the assigned issue.\n\nDepends: load-context","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-21T21:48:26.321647-08:00","updated_at":"2025-12-21T21:48:26.321647-08:00","dependencies":[{"issue_id":"gt-vhby","depends_on_id":"gt-i4lo","type":"parent-child","created_at":"2025-12-21T21:48:26.323953-08:00","created_by":"stevey"},{"issue_id":"gt-vhby","depends_on_id":"gt-tvos","type":"blocks","created_at":"2025-12-21T21:48:26.324548-08:00","created_by":"stevey"}],"wisp":true}
{"id":"gt-vhn1","title":"Test Patrol for Bonding","description":"Parent issue for mol bond CLI test","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-23T22:27:56.627443-08:00","updated_at":"2025-12-23T22:27:56.979927-08:00","closed_at":"2025-12-23T22:27:56.979927-08:00","close_reason":"Closed"}
{"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-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"}