P4: contrib/store — second module (pure-Go SQLite), budget store

Establish the nested persistence module — the architectural reason the core
stays lean: a SEPARATE go.mod carrying modernc.org/sqlite (pure Go, no cgo), so
the SQLite driver NEVER enters the executus core go.sum. A static-binary host
(gadfly) importing only the core stays static; a host wanting turnkey
persistence imports contrib/store.

- sqlite.go: store.Open(dsn) -> *DB (one SQLite file), accessor-per-seam.
- budget_store.go: db.Budget() satisfies budget.BudgetStorage; Add() does the
  7-day window rollover atomically inside a transaction (concurrent Adds can't
  race the read-modify-write — the in-memory store's one weak spot).
- Conformance test: budget.NewDBBudget over the SQLite store passes the SAME
  rolling-window contract as the in-memory store.
- CI: a new step builds + tests contrib/store on its own AND asserts it carries
  the sqlite driver the core forbids (proof the split works). Verified: core
  go.sum has 0 sqlite refs; contrib/store go.sum has it.

persona/skill/audit SQLite stores follow next (same JSON-blob + indexed-columns
pattern, sidestepping the three-layer field-loss footgun).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-26 22:44:44 -04:00
parent 41659b2412
commit 95f564ac4e
8 changed files with 310 additions and 3 deletions
+12
View File
@@ -103,3 +103,15 @@ jobs:
exit 1
fi
echo "OK: core go.sum is free of host/DB dependencies."
- name: contrib/store (nested SQLite module — isolated from core)
run: |
# contrib/store is a SEPARATE module carrying modernc.org/sqlite; the
# core's `go test ./...` doesn't reach it. Build + test it on its own,
# and confirm it DOES carry the driver the core forbids (proof the
# split works: persistence lives here, not in the core go.sum).
cd contrib/store
go build ./...
go test -race -count=1 -timeout 5m ./...
grep -qE 'modernc.org/sqlite' go.sum || { echo "ERROR: contrib/store should carry the sqlite driver"; exit 1; }
echo "OK: contrib/store builds, tests pass, and owns the SQLite dep."