- packages/schema/src/client.ts: createDb(url) -> { db, sql } drizzle/postgres-js
factory. Exposed as the ./client subpath export so the node-only driver never
leaks into client bundles.
- packages/schema/src/db.integration.test.ts: 6 tests gated behind INTEGRATION=1
(content insert/read, vault_path UNIQUE, idempotency_key UNIQUE no-double-post,
content_id FK, audit append, kill-switch upsert). Verified against Postgres 17.
- Default CI suite unchanged: integration tests skip without INTEGRATION.
Closes the Stage 2.1 DoD against a live database (unblocked by Gate 0.8).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes 3 pre-existing TypeScript errors that vitest did not catch but
tsc --noEmit did:
- apps/mcp-linkedin/src/tools.test.ts: spread TOOL_NAMES before .sort()
(readonly tuple has no mutating sort)
- packages/sanitize/src/corpus.test.ts: cast through unknown to FixtureMeta
- db/migrations/rehearse.ts: add 'postgres' driver dependency (also needed
to run the migration itself)
Also: apps/admin test script uses --passWithNoTests (Stage 5 admin app has
no test files yet, vitest exited non-zero on empty).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pure-function pieces that need no Redis/DB to verify (11 new tests):
- apps/scheduler/src/cadence.ts: Beta posterior model, propose(history, config)→[Proposal]; threshold gates (≥8 samples, ≥4 weeks, ≥20% ratio, disjoint 95% CIs); never auto-applied (RBR)
- apps/scheduler/src/publish-loop.ts: state-machine transition function for pending→queued→dispatching→published with retry-vs-DLQ branch on failure and cancellation path
What defers to live Redis + Postgres + LinkedIn:
- 4.1 BullMQ queue + Redis enqueue→consume integration test
- 4.2 End-to-end publish loop trace (POST /api/content → DB → BullMQ → LinkedIn fake → publication row)
- 4.3 Chaos test for idempotency on retry
117/117 tests pass cumulative across all packages and apps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>