bd sync: 2025-12-23 12:27:35

This commit is contained in:
Steve Yegge
2025-12-23 12:27:35 -08:00
parent dc4423bd90
commit 5f15dc49e3

View File

@@ -31,7 +31,7 @@
{"id":"bd-2vh3.3","title":"Tier 2: Basic bd mol squash command","description":"Add bd mol squash command for basic molecule execution compression.\n\n## Command\n\nbd mol squash \u003cmolecule-id\u003e [flags]\n --dry-run Preview what would be squashed\n --keep-children Don't delete ephemeral children after squash\n --json JSON output\n\n## Implementation\n\n1. Find all ephemeral children of molecule (parent-child deps)\n2. Concatenate child descriptions/notes into digest\n3. Create digest issue in main repo with:\n - Title: 'Molecule Execution Summary: \u003coriginal-title\u003e'\n - digest_of: [list of squashed child IDs]\n - ephemeral: false (digest is permanent)\n4. Delete ephemeral children (unless --keep-children)\n5. Link digest to parent work item\n\n## Schema Changes\n\nAdd to Issue struct:\n- SquashedAt *time.Time\n- SquashDigest string (ID of digest)\n- DigestOf []string (IDs of squashed children)\n\n## Acceptance Criteria\n\n- bd mol squash \u003cid\u003e creates digest, removes children\n- --dry-run shows preview\n- Digest has proper metadata linking","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-21T12:57:48.338114-08:00","updated_at":"2025-12-21T13:53:58.974433-08:00","closed_at":"2025-12-21T13:53:58.974433-08:00","close_reason":"Implemented bd mol squash command with tests","dependencies":[{"issue_id":"bd-2vh3.3","depends_on_id":"bd-2vh3","type":"parent-child","created_at":"2025-12-21T12:57:48.338636-08:00","created_by":"stevey"},{"issue_id":"bd-2vh3.3","depends_on_id":"bd-2vh3.2","type":"blocks","created_at":"2025-12-21T12:58:22.601321-08:00","created_by":"stevey"}]}
{"id":"bd-2vh3.4","title":"Tier 3: AI-powered squash summarization","description":"## Design: Agent-Provided Summarization (Inversion of Control)\n\nbd is a tool FOR agents, not an agent itself. The calling agent provides\nthe summary; bd just stores it.\n\n### API\n\n```bash\n# Agent generates summary, passes to bd\nbd mol squash bd-xxx --summary \"Agent-generated summary here\"\n\n# Without --summary, falls back to basic concatenation\nbd mol squash bd-xxx\n```\n\n### Gas Town Integration Pattern\n\n```go\n// In polecat completion handler or witness\nraw := exec.Command(\"bd\", \"mol\", \"show\", molID, \"--json\").Output()\nsummary := callHaiku(buildSummaryPrompt(raw)) // agent's job\nexec.Command(\"bd\", \"mol\", \"squash\", molID, \"--summary\", summary).Run()\n```\n\n### Why This Design\n\n| Concern | bd's job | Agent's job |\n|---------|----------|-------------|\n| Store data | ✅ | |\n| Query data | ✅ | |\n| Generate summaries | | ✅ |\n| Call LLMs | | ✅ |\n| Manage API keys | | ✅ |\n\n### Implementation Status\n\n- [x] --summary flag added to bd mol squash\n- [x] Tests for agent-provided summary\n- [ ] Gas Town integration (separate task)\n\n### Acceptance Criteria\n\n- ✅ bd mol squash --summary uses provided text\n- ✅ Without --summary, falls back to concatenation\n- ✅ No LLM calls in bd itself","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-21T12:58:00.732749-08:00","updated_at":"2025-12-21T14:29:16.288713-08:00","closed_at":"2025-12-21T14:29:16.288713-08:00","close_reason":"Implemented --summary flag for agent-provided summaries. bd stays a pure tool; agents provide the intelligence.","dependencies":[{"issue_id":"bd-2vh3.4","depends_on_id":"bd-2vh3","type":"parent-child","created_at":"2025-12-21T12:58:00.733264-08:00","created_by":"stevey"},{"issue_id":"bd-2vh3.4","depends_on_id":"bd-2vh3.3","type":"blocks","created_at":"2025-12-21T12:58:22.698686-08:00","created_by":"stevey"}]}
{"id":"bd-2vh3.5","title":"Tier 4: Auto-squash on molecule completion","description":"Automatically squash molecules when they reach terminal state.\n\n## Integration Points\n\n1. Hook into molecule completion handler\n2. Detect when all steps are done/failed\n3. Trigger squash automatically\n\n## Config\n\nbd config set mol.auto_squash true # Default: false\nbd config set mol.auto_squash_on_success true # Only on success\nbd config set mol.auto_squash_delay '5m' # Wait before squash\n\n## Implementation Options\n\n### Option A: Post-Completion Hook\nIn mol completion handler:\n- Check if auto_squash enabled\n- Call Squash() after terminal state\n\n### Option B: Git Hook\nIn .beads/hooks/post-commit:\n- bd mol squash --auto\n\n### Option C: Daemon Background Task\n- Daemon periodically checks for squashable molecules\n- Squashes in background\n\n## Acceptance Criteria\n\n- Completed molecules auto-squash without manual intervention\n- Configurable delay before squash\n- Option to squash only on success vs always\n- Works with both daemon and no-daemon modes","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-21T12:58:13.345577-08:00","updated_at":"2025-12-21T17:40:39.794527-08:00","closed_at":"2025-12-21T17:40:39.794527-08:00","close_reason":"Won't fix - cleanup handled via molecule workflows (e.g. daily cleanup plugin)","dependencies":[{"issue_id":"bd-2vh3.5","depends_on_id":"bd-2vh3","type":"parent-child","created_at":"2025-12-21T12:58:13.346152-08:00","created_by":"stevey"},{"issue_id":"bd-2vh3.5","depends_on_id":"bd-2vh3.4","type":"blocks","created_at":"2025-12-21T12:58:22.797141-08:00","created_by":"stevey"}]}
{"id":"bd-2vh3.6","title":"Tier 5 (Future): JSONL archive rotation","description":"Periodic rotation of issues.jsonl for long-running repos.\n\n## Design\n\n.beads/\n├── issues.jsonl # Current (hot)\n├── archive/\n│ ├── issues-2025-12.jsonl.gz # Archived (cold)\n│ └── ...\n└── index.jsonl # Merged index for queries\n\n## Commands\n\nbd archive rotate [flags]\n --older-than N Archive issues closed \u003e N days\n --compress Gzip archives\n --dry-run Preview\n\nbd archive list # Show archived periods\nbd archive restore \u003cperiod\u003e # Restore from archive\n\n## Config\n\nbd config set archive.enabled true\nbd config set archive.rotate_days 90\nbd config set archive.compress true\nbd config set archive.path '.beads/archive'\n\n## Considerations\n\n- Archives can be gitignored (local only) or committed (shared)\n- Query layer must check index, hydrate from archive\n- Cold storage tiering (S3/GCS) for enterprise\n- Merkle proofs preserved for audit\n\n## Priority\n\nThis is post-1.0 work. Current focus is on squash (removes ephemeral).\nArchive helps with long-term history but is less critical.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-21T12:58:38.210008-08:00","updated_at":"2025-12-21T12:58:38.210008-08:00","dependencies":[{"issue_id":"bd-2vh3.6","depends_on_id":"bd-2vh3","type":"parent-child","created_at":"2025-12-21T12:58:38.210543-08:00","created_by":"stevey"}]}
{"id":"bd-2vh3.6","title":"Tier 5 (Future): JSONL archive rotation","description":"Periodic rotation of issues.jsonl for long-running repos.\n\n## Design\n\n.beads/\n├── issues.jsonl # Current (hot)\n├── archive/\n│ ├── issues-2025-12.jsonl.gz # Archived (cold)\n│ └── ...\n└── index.jsonl # Merged index for queries\n\n## Commands\n\nbd archive rotate [flags]\n --older-than N Archive issues closed \u003e N days\n --compress Gzip archives\n --dry-run Preview\n\nbd archive list # Show archived periods\nbd archive restore \u003cperiod\u003e # Restore from archive\n\n## Config\n\nbd config set archive.enabled true\nbd config set archive.rotate_days 90\nbd config set archive.compress true\nbd config set archive.path '.beads/archive'\n\n## Considerations\n\n- Archives can be gitignored (local only) or committed (shared)\n- Query layer must check index, hydrate from archive\n- Cold storage tiering (S3/GCS) for enterprise\n- Merkle proofs preserved for audit\n\n## Priority\n\nThis is post-1.0 work. Current focus is on squash (removes ephemeral).\nArchive helps with long-term history but is less critical.","status":"deferred","priority":4,"issue_type":"feature","created_at":"2025-12-21T12:58:38.210008-08:00","updated_at":"2025-12-23T12:27:02.371921-08:00","dependencies":[{"issue_id":"bd-2vh3.6","depends_on_id":"bd-2vh3","type":"parent-child","created_at":"2025-12-21T12:58:38.210543-08:00","created_by":"stevey"}]}
{"id":"bd-2wh","title":"Test pinned for stats","status":"tombstone","priority":2,"issue_type":"task","created_at":"2025-12-18T21:47:09.334108-08:00","updated_at":"2025-12-18T21:47:25.17917-08:00","deleted_at":"2025-12-18T21:47:25.17917-08:00","deleted_by":"daemon","delete_reason":"delete","original_type":"task"}
{"id":"bd-313v","title":"rpc: Rich mutation events not emitted","description":"The activity command (activity.go) references rich mutation event types (MutationBonded, MutationSquashed, MutationBurned, MutationStatus) that include metadata like OldStatus, NewStatus, ParentID, and StepCount.\n\nHowever, the emitMutation() function in server_core.go:141 only accepts (eventType, issueID) and only populates Type, IssueID, and Timestamp. The additional metadata fields are never set.\n\nNeed to either:\n1. Add an emitRichMutation() function that accepts the additional metadata\n2. Update call sites (close, bond, squash, burn operations) to emit rich events\n\nWithout this fix, the activity feed will never show:\n- Status transitions (in_progress -\u003e closed)\n- Bonded events with step counts\n- Parent molecule relationships\n\nDiscovered during code review of bd-xo1o implementation.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-23T04:06:17.39523-08:00","updated_at":"2025-12-23T04:13:19.205249-08:00","closed_at":"2025-12-23T04:13:19.205249-08:00","close_reason":"Added emitRichMutation() function and updated handleClose/handleUpdate to emit MutationStatus events with old/new status metadata. Added comprehensive tests."}
{"id":"bd-379","title":"Implement `bd setup cursor` for Cursor IDE integration","description":"Create a `bd setup cursor` command that integrates Beads workflow into Cursor IDE via .cursorrules file. Unlike Claude Code (which has hooks), Cursor uses a static rules file to provide context to its AI.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-11T23:32:22.170083-08:00","updated_at":"2025-11-11T23:32:22.170083-08:00"}
@@ -71,7 +71,7 @@
{"id":"bd-66l4","title":"Runtime bonding: bd mol attach","description":"Attach a molecule to an already-running workflow.\n\nCOMMAND: bd mol attach \u003cepic-id\u003e \u003cproto\u003e [--after \u003cissue-id\u003e]\n\nBEHAVIOR:\n- Resolve running epic and proto\n- Spawn proto as new subtree\n- Wire to specified attachment point (or epic root)\n- Handle in-progress issues: new work doesn't block completed work\n\nUSE CASES:\n- Discovered need for docs while implementing feature\n- Hotfix needs attaching to release workflow\n- Additional testing scope identified mid-flight\n\nFLAGS:\n- --after ISSUE: Specific attachment point within epic\n- --type: sequential (default) or parallel\n- --var: Variables for the attached proto\n\nCONSIDERATIONS:\n- What if epic is already closed? Error or reopen?\n- What if attachment point issue is closed? Attach as ready-to-work?","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-21T00:59:16.920483-08:00","updated_at":"2025-12-21T01:08:43.530597-08:00","closed_at":"2025-12-21T01:08:43.530597-08:00","close_reason":"Merged into bd-o91r: bond command handles all bonding cases polymorphically","dependencies":[{"issue_id":"bd-66l4","depends_on_id":"bd-o5xe","type":"parent-child","created_at":"2025-12-21T00:59:51.435542-08:00","created_by":"daemon"},{"issue_id":"bd-66l4","depends_on_id":"bd-o91r","type":"blocks","created_at":"2025-12-21T00:59:51.813782-08:00","created_by":"daemon"}]}
{"id":"bd-66w1","title":"Add external_projects to config schema","description":"Add external_projects mapping to .beads/config.yaml:\n\n```yaml\nexternal_projects:\n beads: ../beads\n gastown: ../gastown\n other: /absolute/path/to/project\n```\n\nUsed by bd ready and other commands to resolve external: references.\n\nPart of cross-project dependency system.\nSee: gastown/docs/cross-project-deps.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-21T22:37:39.245017-08:00","updated_at":"2025-12-21T23:03:19.81448-08:00","closed_at":"2025-12-21T23:03:19.81448-08:00","close_reason":"Added external_projects to config schema with GetExternalProjects() and ResolveExternalProjectPath() functions, tests, and documentation"}
{"id":"bd-687g","title":"Code review: mol squash deletion bypasses tombstone system","description":"The deleteEphemeralChildren function in mol_squash.go uses DeleteIssue directly instead of the proper deletion flow. This bypasses tombstone creation, deletion tracking (deletions.jsonl), and dependency cleanup. Could cause issues with deletion propagation across clones.\n\nCurrent code uses d.DeleteIssue(ctx, id) but should probably use d.DeleteIssues(ctx, ids, false, true, false) for proper tombstone handling.\n\nAlternative: Document that ephemeral issues intentionally use hard delete since they are transient and should never propagate to other clones anyway.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-21T13:57:20.223345-08:00","updated_at":"2025-12-21T14:17:38.073899-08:00","closed_at":"2025-12-21T14:17:38.073899-08:00","close_reason":"Implemented ephemeral issue filtering from JSONL export and fixed comments leak in DeleteIssue"}
{"id":"bd-687v","title":"Consider caching external dep resolution results","description":"Each call to GetReadyWork re-checks all external dependencies by:\n1. Querying for external deps in the local database\n2. Opening each external project's database\n3. Querying for closed issues with provides: labels\n\nFor workloads with many external deps or slow external databases, this adds latency on every bd ready call.\n\nPotential optimizations:\n- In-memory TTL cache for external dep status (e.g., 60 second TTL)\n- Store resolved status in a local cache table with timestamp\n- Batch resolution of common project/capability pairs\n\nThis is not urgent - current implementation is correct and performant for typical workloads. Only becomes an issue with many external deps across many projects.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-21T23:45:16.360877-08:00","updated_at":"2025-12-21T23:45:16.360877-08:00","dependencies":[{"issue_id":"bd-687v","depends_on_id":"bd-zmmy","type":"discovered-from","created_at":"2025-12-21T23:45:16.361493-08:00","created_by":"daemon"}]}
{"id":"bd-687v","title":"Consider caching external dep resolution results","description":"Each call to GetReadyWork re-checks all external dependencies by:\n1. Querying for external deps in the local database\n2. Opening each external project's database\n3. Querying for closed issues with provides: labels\n\nFor workloads with many external deps or slow external databases, this adds latency on every bd ready call.\n\nPotential optimizations:\n- In-memory TTL cache for external dep status (e.g., 60 second TTL)\n- Store resolved status in a local cache table with timestamp\n- Batch resolution of common project/capability pairs\n\nThis is not urgent - current implementation is correct and performant for typical workloads. Only becomes an issue with many external deps across many projects.","status":"deferred","priority":3,"issue_type":"task","created_at":"2025-12-21T23:45:16.360877-08:00","updated_at":"2025-12-23T12:27:02.223409-08:00","dependencies":[{"issue_id":"bd-687v","depends_on_id":"bd-zmmy","type":"discovered-from","created_at":"2025-12-21T23:45:16.361493-08:00","created_by":"daemon"}]}
{"id":"bd-68bf","title":"Code review: bd mol bond implementation","description":"Review the mol bond command implementation before shipping.\n\nFocus areas:\n1. runMolBond() - polymorphic dispatch logic correctness\n2. bondProtoProto() - compound proto creation, dependency wiring\n3. bondProtoMol() / bondMolProto() - spawn and attach logic\n4. bondMolMol() - joining molecules, lineage tracking\n5. BondRef usage - is lineage tracked correctly?\n6. Error handling - are all failure modes covered?\n7. Edge cases - what could go wrong?\n\nFile: cmd/bd/mol.go (lines 485-859)\nCommit: 386b513e","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-21T10:13:09.425229-08:00","updated_at":"2025-12-21T11:18:14.206869-08:00","closed_at":"2025-12-21T11:18:14.206869-08:00","close_reason":"Reviewed and fixed label persistence bug","dependencies":[{"issue_id":"bd-68bf","depends_on_id":"bd-o91r","type":"discovered-from","created_at":"2025-12-21T10:13:09.426471-08:00","created_by":"daemon"}]}
{"id":"bd-68e4","title":"doctor --fix should export when DB has more issues than JSONL","description":"When 'bd doctor' detects a count mismatch (DB has more issues than JSONL), it currently recommends 'bd sync --import-only', which imports JSONL into DB. But JSONL is the source of truth, not the DB.\n\n**Current behavior:**\n- Doctor detects: DB has 355 issues, JSONL has 292\n- Recommends: 'bd sync --import-only' \n- User runs it: Returns '0 created, 0 updated' (no-op, because JSONL hasn't changed)\n- User is stuck\n\n**Root cause:**\nThe doctor fix is one-directional (JSONL→DB) when it should be bidirectional. If DB has MORE issues, they haven't been exported yet - the fix should be 'bd export' (DB→JSONL), not import.\n\n**Desired fix:**\nIn fix.DBJSONLSync(), detect which has more data:\n- If DB \u003e JSONL: Run 'bd export' to sync JSONL (since DB is the working copy)\n- If JSONL \u003e DB: Run 'bd sync --import-only' to import (JSONL is source of truth)\n- If equal but timestamps differ: Detect based on file mtime\n\nThis makes 'bd doctor --fix' actually fix the problem instead of being a no-op.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-21T11:17:20.994319182-07:00","updated_at":"2025-12-21T11:23:24.38523731-07:00","closed_at":"2025-12-21T11:23:24.38523731-07:00"}
{"id":"bd-6fe4622f","title":"Remove unreachable utility functions","description":"Several small utility functions are unreachable:\n\nFiles to clean:\n1. `internal/storage/sqlite/hash.go` - `computeIssueContentHash` (line 17)\n - Check if entire file can be deleted if only contains this function\n\n2. `internal/config/config.go` - `FileUsed` (line 151)\n - Delete unused config helper\n\n3. `cmd/bd/git_sync_test.go` - `verifyIssueOpen` (line 300)\n - Delete dead test helper\n\n4. `internal/compact/haiku.go` - `HaikuClient.SummarizeTier2` (line 81)\n - Tier 2 summarization not implemented\n - Options: implement feature OR delete method\n\nImpact: Removes 50-100 LOC depending on decisions","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.434573-07:00","updated_at":"2025-12-17T22:58:34.563993-08:00","closed_at":"2025-12-17T22:58:34.563993-08:00","close_reason":"Closed"}
@@ -220,7 +220,7 @@
{"id":"bd-fu83","title":"Fix daemon/direct mode inconsistency in relate and duplicate commands","description":"The relate.go and duplicate.go commands have inconsistent daemon/direct mode handling:\n\nWhen daemonClient is connected, they resolve IDs via RPC but then perform updates directly via store.UpdateIssue(), bypassing the daemon.\n\nAffected locations:\n- relate.go:125-139 (runRelate update)\n- relate.go:235-246 (runUnrelate update) \n- duplicate.go:120 (runDuplicate update)\n- duplicate.go:207 (runSupersede update)\n\nShould either use RPC for updates when daemon is running, or document why direct access is intentional.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-16T20:52:54.164189-08:00","updated_at":"2025-12-21T21:47:14.10222-08:00","closed_at":"2025-12-21T21:47:14.10222-08:00","close_reason":"Already implemented in commit 3ec517cc: relate, unrelate, duplicate, supersede now use RPC Update when daemon available"}
{"id":"bd-fx7v","title":"Improve test coverage for cmd/bd/doctor/fix (23.9% → 50%)","description":"The doctor/fix package has only 23.9% test coverage. The doctor fix functionality is important for troubleshooting.\n\nCurrent coverage: 23.9%\nTarget coverage: 50%","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T20:43:05.67127-08:00","updated_at":"2025-12-13T21:01:20.839298-08:00"}
{"id":"bd-fy4q","title":"Phase 1.2 follow-up: Clarify format storage","description":"Phase 1.2 created the bdt executable structure but issues.toon is currently stored in JSONL format, not TOON format.\n\nThis is intentional for now:\n- Phase 1.2 (bd-jv4w): Just infrastructure - separate binary, separate directory\n- Phase 1.3 (bd-j0tr): Implement actual TOON encoding/writing\n\nFor now, keep as-is: filename '.toon' signals intent, content is JSONL (interim format). Phase 1.3 will switch to actual TOON.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-19T14:03:19.491040345-07:00","updated_at":"2025-12-19T14:03:19.491040345-07:00","dependencies":[{"issue_id":"bd-fy4q","depends_on_id":"bd-jv4w","type":"discovered-from","created_at":"2025-12-19T14:03:19.498933555-07:00","created_by":"daemon"}]}
{"id":"bd-g4b4","title":"bd close hooks: context check and notifications","description":"Add hook system to bd close for context checking and notifications.\n\n## Concept\n\nRegister hooks that run on every bd close:\n\n# .beads/config.yaml\nhooks:\n on_close:\n - command: 'gt context-check'\n - notify: 'Next step ready'\n\n## Use cases\n\n### Context check on close\nAfter closing a step, check if context is getting full.\nIf \u003e80%, output warning suggesting session cycling.\n\n### Next step notification \nAutomatically show next ready step (complements --continue).\n\n### Custom actions\nUser-defined scripts for workflow automation.\n\n## Hook types\n\n- command: Run shell command with env vars (BEAD_ID, BEAD_TITLE, etc)\n- notify: Send message to agent\n- webhook: POST to URL (future)\n\n## Integration with context detection\n\nThe context-check hook could:\n1. Capture tmux pane (if in tmux session)\n2. Estimate context usage (turn count, output length)\n3. If high, output: 'Context at ~85%. Consider cycling.'\n\n## Priority\nP2 - nice to have, not blocking launch.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-22T17:03:56.183461-08:00","updated_at":"2025-12-22T17:25:17.139071-08:00"}
{"id":"bd-g4b4","title":"bd close hooks: context check and notifications","description":"Add hook system to bd close for notifications and custom actions.\n\n## Scope (MVP)\n\nImplement **command hooks only** for bd close. Deferred: notify, webhook types.\n\n## Implementation\n\n### 1. Config Schema\n\nAdd to internal/configfile/config.go:\n\n```go\ntype HooksConfig struct {\n OnClose []HookEntry `yaml:\"on_close,omitempty\"`\n}\n\ntype HookEntry struct {\n Command string `yaml:\"command\"` // Shell command to run\n Name string `yaml:\"name,omitempty\"` // Optional display name\n}\n```\n\nAdd `Hooks HooksConfig` field to Config struct.\n\n### 2. Hook Execution\n\nCreate internal/hooks/close_hooks.go:\n\n```go\nfunc RunCloseHooks(ctx context.Context, cfg *configfile.Config, issue *types.Issue) error {\n for _, hook := range cfg.Hooks.OnClose {\n cmd := exec.CommandContext(ctx, \"sh\", \"-c\", hook.Command)\n cmd.Env = append(os.Environ(),\n \"BEAD_ID=\"+issue.ID,\n \"BEAD_TITLE=\"+issue.Title,\n \"BEAD_TYPE=\"+string(issue.IssueType),\n \"BEAD_PRIORITY=\"+strconv.Itoa(issue.Priority),\n \"BEAD_CLOSE_REASON=\"+issue.CloseReason,\n )\n cmd.Stdout = os.Stdout\n cmd.Stderr = os.Stderr\n if err := cmd.Run(); err \\!= nil {\n // Log warning but dont fail the close\n fmt.Fprintf(os.Stderr, \"Warning: close hook %q failed: %v\\n\", hook.Name, err)\n }\n }\n return nil\n}\n```\n\n### 3. Integration Point\n\nIn cmd/bd/close.go, after successful close:\n\n```go\n// Run close hooks\nif cfg := configfile.Load(); cfg \\!= nil {\n hooks.RunCloseHooks(ctx, cfg, closedIssue)\n}\n```\n\n### 4. Example Config\n\n```yaml\n# .beads/config.yaml\nhooks:\n on_close:\n - name: show-next\n command: bd ready --limit 1\n - name: context-check \n command: echo \"Issue $BEAD_ID closed. Check context if nearing limit.\"\n```\n\n## Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| BEAD_ID | Issue ID (e.g., bd-abc1) |\n| BEAD_TITLE | Issue title |\n| BEAD_TYPE | Issue type (task, bug, feature, etc.) |\n| BEAD_PRIORITY | Priority (0-4) |\n| BEAD_CLOSE_REASON | Close reason if provided |\n\n## Testing\n\nAdd test in internal/hooks/close_hooks_test.go:\n- Test hook execution with mock config\n- Test env vars are set correctly\n- Test hook failure doesnt block close\n\n## Files to Create/Modify\n\n1. **Create:** internal/hooks/close_hooks.go\n2. **Create:** internal/hooks/close_hooks_test.go \n3. **Modify:** internal/configfile/config.go (add HooksConfig)\n4. **Modify:** cmd/bd/close.go (call RunCloseHooks)\n5. **Modify:** docs/CONFIG.md (document hooks config)\n\n## Out of Scope (Future)\n\n- notify hook type (gt mail integration)\n- webhook type (HTTP POST)\n- on_create, on_update hooks\n- Hook timeout configuration\n- Parallel hook execution","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-22T17:03:56.183461-08:00","updated_at":"2025-12-23T12:27:35.531819-08:00"}
{"id":"bd-g9eu","title":"Investigate TestRoutingIntegration failure","description":"TestRoutingIntegration/maintainer_with_SSH_remote failed during pre-commit check with \"expected role maintainer, got contributor\".\nThis occurred while running `go test -short ./...` on darwin/arm64.\nThe failure appears unrelated to storage/sqlite changes.\nNeed to investigate if this is a flaky test or environmental issue.","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T15:55:19.337094-08:00","updated_at":"2025-11-20T15:55:19.337094-08:00"}
{"id":"bd-gjla","title":"Test Thread","description":"Initial message for threading test","status":"tombstone","priority":2,"issue_type":"message","created_at":"2025-12-16T18:19:51.704324-08:00","updated_at":"2025-12-17T16:11:17.070763-08:00","dependencies":[{"issue_id":"bd-gjla","depends_on_id":"bd-f5cc","type":"duplicates","created_at":"2025-12-18T13:45:31.137191-08:00","created_by":"migration"}],"deleted_at":"2025-12-17T16:11:17.070763-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"message"}
{"id":"bd-gocx","title":"Run bump-version.sh 0.32.1","description":"Execute ./scripts/bump-version.sh 0.32.1 to update all version references","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-20T21:53:18.470174-08:00","updated_at":"2025-12-20T21:54:54.500836-08:00","closed_at":"2025-12-20T21:54:54.500836-08:00","close_reason":"Version bumped to 0.32.1","dependencies":[{"issue_id":"bd-gocx","depends_on_id":"bd-an4s","type":"parent-child","created_at":"2025-12-20T21:53:18.471793-08:00","created_by":"daemon"},{"issue_id":"bd-gocx","depends_on_id":"bd-x3j8","type":"blocks","created_at":"2025-12-20T21:53:29.688436-08:00","created_by":"daemon"}]}
@@ -484,6 +484,6 @@
{"id":"bd-zgb9","title":"gt polecat done should auto-stop running session","description":"Currently 'gt polecat done' fails if session is running, requiring a separate 'gt session stop' first. This is unnecessary friction - done should just stop the session automatically since that's always what you want.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-23T04:11:23.899653-08:00","updated_at":"2025-12-23T04:12:13.029479-08:00","closed_at":"2025-12-23T04:12:13.029479-08:00","close_reason":"Moving to gastown - this is a gt issue not bd"}
{"id":"bd-ziy5","title":"GH#409: bd init uses issues.jsonl but docs say beads.jsonl","description":"bd init creates config referencing issues.jsonl but README/docs reference beads.jsonl as canonical. Standardize naming. See GitHub issue #409.","status":"tombstone","priority":2,"issue_type":"bug","created_at":"2025-12-16T01:03:58.109954-08:00","updated_at":"2025-12-17T16:11:17.070763-08:00","deleted_at":"2025-12-17T16:11:17.070763-08:00","deleted_by":"batch delete","delete_reason":"batch delete","original_type":"bug"}
{"id":"bd-zmmy","title":"bd ready resolves external dependencies","description":"Extend bd ready to check external blocked_by references:\n\n1. Parse external:\u003cproject\u003e:\u003ccapability\u003e from blocked_by\n2. Look up project path from external_projects config\n3. Check if target project has provides:\u003ccapability\u003e label on a closed issue\n4. If not satisfied, issue is blocked\n\nExample output:\n```bash\nbd ready\n# gt-xyz: blocked by external:beads:mol-run-assignee (not provided)\n# gt-abc: ready\n```\n\nDepends on: bd-om4a (external: prefix), bd-66w1 (config)\n\nPart of cross-project dependency system.\nSee: gastown/docs/cross-project-deps.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-21T22:37:50.03794-08:00","updated_at":"2025-12-21T23:42:25.042402-08:00","closed_at":"2025-12-21T23:42:25.042402-08:00","close_reason":"Implemented external dep resolution in GetReadyWork - filters issues with unsatisfied external:project:capability deps","dependencies":[{"issue_id":"bd-zmmy","depends_on_id":"bd-om4a","type":"blocks","created_at":"2025-12-21T22:38:38.106657-08:00","created_by":"daemon"},{"issue_id":"bd-zmmy","depends_on_id":"bd-66w1","type":"blocks","created_at":"2025-12-21T22:38:38.175633-08:00","created_by":"daemon"}]}
{"id":"bd-zt59","title":"Deferred HOP schema additions (P2/P3)","description":"Deferred from bd-7pwh after review. Add when semantics are clearer and actually needed:\n\n- assignee_ref: Structured EntityRef alongside string assignee\n- work_type: 'mutex' vs 'open_competition' (everything is mutex in v0.1)\n- crystallizes: bool for work that compounds vs evaporates (can derive from issue_type)\n- cross_refs: URIs to beads in other repos (needs federation first)\n- skill_vector: []float32 embeddings placeholder (YAGNI)\n\nThese can be added later without breaking changes (all optional fields).","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-22T17:54:20.02496-08:00","updated_at":"2025-12-22T17:54:20.02496-08:00"}
{"id":"bd-zw72","title":"Investigate incremental blocked_issues_cache updates at scale","description":"Current blocked_issues_cache strategy does full DELETE + INSERT on every dependency/status change.\n\n**Problem at scale:**\n- 10K issues: ~50ms rebuild (acceptable)\n- 100K issues: ~500ms rebuild (noticeable)\n- 1M issues: multi-second rebuilds (problematic)\n\n**Current implementation (blocked_cache.go:104-154):**\n- DELETE FROM blocked_issues_cache\n- INSERT with recursive CTE\n\n**Potential optimizations:**\n1. **Incremental updates:** Only add/remove affected issue IDs instead of full rebuild\n2. **Dirty tracking:** Skip rebuild if cache is already valid\n3. **Async rebuild:** Rebuild in background, serve stale cache briefly\n4. **Partial invalidation:** Only invalidate affected subtree\n\n**Decision needed:** Is this premature optimization? Current target is \u003c100K issues.\n\n**Benchmark:** Add benchmark for cache rebuild at 100K scale to measure actual impact.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-22T22:58:55.165718-08:00","updated_at":"2025-12-22T22:58:55.165718-08:00","dependencies":[{"issue_id":"bd-zw72","depends_on_id":"bd-h0we","type":"discovered-from","created_at":"2025-12-22T22:58:55.166427-08:00","created_by":"daemon"}]}
{"id":"bd-zt59","title":"Deferred HOP schema additions (P2/P3)","description":"Deferred from bd-7pwh after review. Add when semantics are clearer and actually needed:\n\n- assignee_ref: Structured EntityRef alongside string assignee\n- work_type: 'mutex' vs 'open_competition' (everything is mutex in v0.1)\n- crystallizes: bool for work that compounds vs evaporates (can derive from issue_type)\n- cross_refs: URIs to beads in other repos (needs federation first)\n- skill_vector: []float32 embeddings placeholder (YAGNI)\n\nThese can be added later without breaking changes (all optional fields).","status":"deferred","priority":4,"issue_type":"task","created_at":"2025-12-22T17:54:20.02496-08:00","updated_at":"2025-12-23T12:27:02.445219-08:00"}
{"id":"bd-zw72","title":"Investigate incremental blocked_issues_cache updates at scale","description":"Current blocked_issues_cache strategy does full DELETE + INSERT on every dependency/status change.\n\n**Problem at scale:**\n- 10K issues: ~50ms rebuild (acceptable)\n- 100K issues: ~500ms rebuild (noticeable)\n- 1M issues: multi-second rebuilds (problematic)\n\n**Current implementation (blocked_cache.go:104-154):**\n- DELETE FROM blocked_issues_cache\n- INSERT with recursive CTE\n\n**Potential optimizations:**\n1. **Incremental updates:** Only add/remove affected issue IDs instead of full rebuild\n2. **Dirty tracking:** Skip rebuild if cache is already valid\n3. **Async rebuild:** Rebuild in background, serve stale cache briefly\n4. **Partial invalidation:** Only invalidate affected subtree\n\n**Decision needed:** Is this premature optimization? Current target is \u003c100K issues.\n\n**Benchmark:** Add benchmark for cache rebuild at 100K scale to measure actual impact.","status":"deferred","priority":3,"issue_type":"task","created_at":"2025-12-22T22:58:55.165718-08:00","updated_at":"2025-12-23T12:27:02.297059-08:00","dependencies":[{"issue_id":"bd-zw72","depends_on_id":"bd-h0we","type":"discovered-from","created_at":"2025-12-22T22:58:55.166427-08:00","created_by":"daemon"}]}
{"id":"bd-zwtq","title":"Run bd doctor at end of bd init to verify setup","description":"Run bd doctor diagnostics at end of bd init (after line 398 in init.go). If issues found, warn user immediately: '⚠ Setup incomplete. Run bd doctor --fix to complete setup.' Catches configuration problems before user encounters them in normal workflow.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-21T23:16:09.596778-08:00","updated_at":"2025-12-23T04:20:51.887338-08:00","closed_at":"2025-12-23T04:20:51.887338-08:00","close_reason":"Already implemented in commits ec4117d0 and 3a36d0b9 - hooks/merge driver install by default, doctor runs at end of init","dependencies":[{"issue_id":"bd-zwtq","depends_on_id":"bd-tbz3","type":"parent-child","created_at":"2025-11-21T23:16:09.597617-08:00","created_by":"daemon","metadata":"{}"}]}