Update beads database: close bd-159, bd-160, create bd-166

Amp-Thread-ID: https://ampcode.com/threads/T-b554e049-aff8-4a24-8bf3-3305483b7f5a
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-25 23:11:52 -07:00
parent daa25db720
commit fbaaedce53

View File

@@ -81,7 +81,7 @@
{"id":"bd-21","title":"Phase 2: Implement VCStorage Wrapper","description":"Create VCStorage wrapper that embeds beads.Storage and adds VC-specific operations.\n\n**Goal:** Build clean abstraction layer where VC extends Beads without modifying Beads library.\n\n**Architecture:**\n- VCStorage embeds beads.Storage (delegates core operations)\n- VCStorage adds VC-specific methods (executor instances, events)\n- Same database, separate table namespaces (Beads tables + VC tables)\n- Zero changes to Beads library code\n\n**Key Tasks:**\n1. Create VCStorage struct that embeds beads.Storage\n2. Implement VC-specific methods: CreateExecutorInstance(), GetStaleExecutors(), LogEvent(), UpdateExecutionState()\n3. Create VC table schemas (executor_instances, issue_execution_state, agent_events)\n4. Verify type compatibility between VC types.Issue and Beads Issue\n5. Create MockVCStorage for testing\n6. Write unit tests for VC-specific methods\n7. Write integration tests (end-to-end with Beads)\n8. Benchmark performance vs current SQLite\n9. Verify NO changes needed to Beads library\n\n**Acceptance Criteria:**\n- VCStorage successfully wraps Beads storage (embedding works)\n- VC-specific tables created and accessible via foreign keys to Beads tables\n- VC-specific methods work (executor instances, events)\n- Core operations delegate to Beads correctly\n- Tests pass with \u003e90% coverage\n- Performance benchmark shows no regression\n- Beads library remains unmodified and standalone\n\n**Technical Details:**\n- Use beadsStore.DB() to get underlying database connection\n- Create VC tables with FOREIGN KEY references to Beads issues table\n- Schema separation: Beads owns (issues, dependencies, labels), VC owns (executor_instances, agent_events)\n- Testing: Embed MockBeadsStorage in MockVCStorage\n\n**Dependencies:**\n- Blocked by Phase 1 (need Beads library imported)\n\n**Estimated Effort:** 1.5 sprints","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-22T14:04:36.674165-07:00","updated_at":"2025-10-24T13:51:54.398392-07:00","closed_at":"2025-10-22T21:37:48.747033-07:00","dependencies":[{"issue_id":"bd-21","depends_on_id":"bd-19","type":"parent-child","created_at":"2025-10-24T13:17:40.321936-07:00","created_by":"renumber"},{"issue_id":"bd-21","depends_on_id":"bd-20","type":"blocks","created_at":"2025-10-24T13:17:40.322171-07:00","created_by":"renumber"}]}
{"id":"bd-22","title":"Phase 3: Migration Path \u0026 Database Schema Alignment","description":"Enable existing .beads/vc.db files to work with Beads library through automated migration.\n\n**Goal:** Provide safe, tested migration path from SQLite implementation to Beads library.\n\n**Key Tasks:**\n1. Run compatibility tests against production databases\n2. Identify schema differences (columns, indexes, constraints)\n3. Document required migrations\n4. Create migration CLI command: 'vc migrate --from sqlite --to beads'\n5. Add dry-run mode for preview\n6. Add backup/restore capability\n7. Implement rollback mechanism\n8. Add auto-detection of schema version on startup\n9. Add auto-migrate with user prompt\n\n**Acceptance Criteria:**\n- Existing databases migrate successfully\n- Data integrity preserved (zero data loss verified via checksums)\n- Rollback works if migration fails\n- Migration tested on real production VC databases\n- Dry-run mode shows exactly what will change\n- Backup created before migration\n- Feature flag: VC_FORCE_SQLITE=true provides escape hatch\n\n**Technical Details:**\n- Compare current SQLite schema with Beads schema\n- Handle version detection (read schema_version or detect from structure)\n- Migration should be idempotent (safe to run multiple times)\n- Backup strategy: Copy .beads/vc.db to .beads/vc.db.backup-\u003ctimestamp\u003e\n- Verify foreign key integrity after migration\n\n**Safety Measures:**\n- Require executor shutdown before migration (check for running executors)\n- Atomic migration (BEGIN IMMEDIATE transaction)\n- Comprehensive pre/post migration validation\n- Clear error messages with recovery instructions\n\n**Dependencies:**\n- Blocked by Phase 2 (need VCStorage implementation)\n\n**Estimated Effort:** 0.5 sprint","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-22T14:04:51.320435-07:00","updated_at":"2025-10-24T13:51:54.399455-07:00","closed_at":"2025-10-22T21:37:48.748273-07:00","dependencies":[{"issue_id":"bd-22","depends_on_id":"bd-19","type":"parent-child","created_at":"2025-10-24T13:17:40.323317-07:00","created_by":"renumber"},{"issue_id":"bd-22","depends_on_id":"bd-21","type":"blocks","created_at":"2025-10-24T13:17:40.323527-07:00","created_by":"renumber"}]}
{"id":"bd-23","title":"Phase 4: Gradual Cutover \u0026 Production Rollout","description":"Replace SQLite implementation with Beads library in production and remove legacy code.\n\n**Goal:** Complete transition to Beads library, deprecate and remove custom SQLite implementation.\n\n**Key Tasks:**\n1. Run VC executor with Beads library in CI\n2. Dogfood: Use Beads library for VC's own development\n3. Monitor for regressions and performance issues\n4. Flip feature flag: VC_USE_BEADS_LIBRARY=true by default\n5. Monitor production logs for errors\n6. Collect user feedback\n7. Add deprecation notice to CLAUDE.md\n8. Provide migration guide for users\n9. Remove legacy code: internal/storage/sqlite/sqlite.go (~1500 lines)\n10. Remove migration framework: internal/storage/migrations/\n11. Remove manual transaction management code\n12. Update all documentation\n\n**Acceptance Criteria:**\n- Beads library enabled by default in production\n- Zero production incidents related to migration\n- Performance meets or exceeds SQLite implementation\n- All tests passing with Beads library\n- Legacy SQLite code removed\n- Documentation updated\n- Celebration documented 🎉\n\n**Rollout Strategy:**\n1. Week 1: Enable for CI/testing environments\n2. Week 2: Dogfood on VC development\n3. Week 3: Enable for 50% of production (canary)\n4. Week 4: Enable for 100% of production\n5. Week 5: Remove legacy code\n\n**Monitoring:**\n- Track error rates before/after cutover\n- Monitor database query performance\n- Track issue creation/update latency\n- Monitor executor claim performance\n\n**Rollback Plan:**\n- Keep VC_FORCE_SQLITE=true escape hatch for 2 weeks post-cutover\n- Keep legacy code for 1 sprint after cutover\n- Document rollback procedure\n\n**Success Metrics:**\n- Zero data loss\n- No performance regression (\u003c 5% latency increase acceptable)\n- Reduced maintenance burden (code LOC reduction)\n- Positive developer feedback\n\n**Dependencies:**\n- Blocked by Phase 3 (need migration tooling)\n\n**Estimated Effort:** 1 sprint","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-22T14:05:07.755107-07:00","updated_at":"2025-10-24T13:51:54.401936-07:00","closed_at":"2025-10-22T21:37:48.748919-07:00","dependencies":[{"issue_id":"bd-23","depends_on_id":"bd-19","type":"parent-child","created_at":"2025-10-24T13:17:40.324637-07:00","created_by":"renumber"},{"issue_id":"bd-23","depends_on_id":"bd-22","type":"blocks","created_at":"2025-10-24T13:17:40.324851-07:00","created_by":"renumber"}]}
{"id":"bd-24","title":"Example library-created issue","description":"This issue was created programmatically using Beads as a library","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-22T14:34:44.081801-07:00","updated_at":"2025-10-24T13:51:54.402932-07:00","closed_at":"2025-10-22T14:34:44.084241-07:00","labels":["library-usage"],"dependencies":[{"issue_id":"bd-24","depends_on_id":"bd-4","type":"discovered-from","created_at":"2025-10-24T13:31:30.930671-07:00","created_by":"import"},{"issue_id":"bd-24","depends_on_id":"bd-125","type":"discovered-from","created_at":"2025-10-24T13:45:29.804656-07:00","created_by":"stevey"}]}
{"id":"bd-24","title":"Example library-created issue","description":"This issue was created programmatically using Beads as a library","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-22T14:34:44.081801-07:00","updated_at":"2025-10-24T13:51:54.402932-07:00","closed_at":"2025-10-22T14:34:44.084241-07:00","labels":["library-usage"],"dependencies":[{"issue_id":"bd-24","depends_on_id":"bd-4","type":"discovered-from","created_at":"2025-10-24T13:31:30.930671-07:00","created_by":"import"},{"issue_id":"bd-24","depends_on_id":"bd-125","type":"discovered-from","created_at":"2025-10-24T13:45:29.804656-07:00","created_by":"stevey"}],"comments":[{"id":1,"issue_id":"bd-24","author":"library-example","text":"This is a programmatic comment","created_at":"2025-10-26T06:04:09Z"}]}
{"id":"bd-25","title":"Add lifecycle safety docs and tests for UnderlyingDB() method","description":"The new UnderlyingDB() method exposes the raw *sql.DB connection for extensions like VC to create their own tables. While database/sql is concurrency-safe, there are lifecycle and misuse risks that need documentation and testing.\n\n**What needs to be done:**\n\n1. **Enhanced documentation** - Expand UnderlyingDB() comments to warn:\n - Callers MUST NOT call Close() on returned DB\n - Do NOT change pool/driver settings (SetMaxOpenConns, SetConnMaxIdleTime)\n - Do NOT modify SQLite PRAGMAs (WAL mode, journal, etc.)\n - Expect errors after Storage.Close() - use contexts\n - Keep write transactions short to avoid blocking core storage\n\n2. **Add lifecycle tracking** - Implement closed flag:\n - Add atomic.Bool closed field to SQLiteStorage\n - Set flag in Close(), clear in New()\n - Optional: Add IsClosed() bool method\n\n3. **Add safety tests** (run with -race):\n - TestUnderlyingDB_ConcurrentAccess - N goroutines using UnderlyingDB() during normal storage ops\n - TestUnderlyingDB_AfterClose - Verify operations fail cleanly after storage closed\n - TestUnderlyingDB_CreateExtensionTables - Create VC table with FK to issues, verify FK enforcement\n - TestUnderlyingDB_LongTxDoesNotCorrupt - Ensure long read tx doesn't block writes indefinitely\n\n**Why this matters:**\nVC will use this to create tables in the same database. Need to ensure production-ready safety without over-engineering.\n\n**Estimated effort:** S+S+S = M total (1-3h)","design":"Oracle recommends \"simple path\": enhanced docs + minimal guardrails + focused tests. See oracle output for detailed rationale on concurrency safety, lifecycle risks, and when to consider advanced path (wrapping interface).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T17:07:56.812983-07:00","updated_at":"2025-10-24T13:51:54.403868-07:00","closed_at":"2025-10-22T20:10:52.636372-07:00"}
{"id":"bd-26","title":"Update EXTENDING.md with UnderlyingDB() usage and best practices","description":"EXTENDING.md currently shows how to use direct sql.Open() to access the database, but doesn't mention the new UnderlyingDB() method that's the recommended way for extensions.\n\n**Update needed:**\n1. Add section showing UnderlyingDB() usage:\n ```go\n store, err := beads.NewSQLiteStorage(dbPath)\n db := store.UnderlyingDB()\n // Create extension tables using db\n ```\n\n2. Document when to use UnderlyingDB() vs direct sql.Open():\n - Use UnderlyingDB() when you want to share the storage connection\n - Use sql.Open() when you need independent connection management\n\n3. Add safety warnings (cross-reference from UnderlyingDB() docs):\n - Don't close the DB\n - Don't modify pool settings\n - Keep transactions short\n\n4. Update the VC example to show UnderlyingDB() pattern\n\n5. Explain beads.Storage.UnderlyingDB() in the API section","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T17:07:56.820056-07:00","updated_at":"2025-10-24T13:51:54.404615-07:00","closed_at":"2025-10-22T19:41:19.895847-07:00","dependencies":[{"issue_id":"bd-26","depends_on_id":"bd-18","type":"discovered-from","created_at":"2025-10-24T13:17:40.32522-07:00","created_by":"renumber"}]}
{"id":"bd-27","title":"Consider adding UnderlyingConn(ctx) for safer scoped DB access","description":"Currently UnderlyingDB() returns *sql.DB which is correct for most uses, but for extension migrations/DDL, a scoped connection might be safer.\n\n**Proposal:** Add optional UnderlyingConn(ctx) (*sql.Conn, error) method that:\n- Returns a scoped connection via s.db.Conn(ctx)\n- Encourages lifetime-bounded usage\n- Reduces temptation to tune global pool settings\n- Better for one-time DDL operations like CREATE TABLE\n\n**Implementation:**\n```go\n// UnderlyingConn returns a single connection from the pool for scoped use\n// Useful for migrations and DDL. Close the connection when done.\nfunc (s *SQLiteStorage) UnderlyingConn(ctx context.Context) (*sql.Conn, error) {\n return s.db.Conn(ctx)\n}\n```\n\n**Benefits:**\n- Safer for migrations (explicit scope)\n- Complements UnderlyingDB() for different use cases\n- Low implementation cost\n\n**Trade-off:** Adds another method to maintain, but Oracle considers this balanced compromise between safety and flexibility.\n\n**Decision:** This is optional - evaluate based on VC's actual usage patterns.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-22T17:07:56.832638-07:00","updated_at":"2025-10-24T13:51:54.405456-07:00","closed_at":"2025-10-22T22:02:18.479512-07:00","dependencies":[{"issue_id":"bd-27","depends_on_id":"bd-18","type":"related","created_at":"2025-10-24T13:17:40.325463-07:00","created_by":"renumber"}]}