feat(storage): opt-in Postgres backend - #132
Merged
Merged
Conversation
Add a Postgres implementation of the Store interface for HA / multi-instance setups, selected by setting RISKKERNEL_DATABASE_URL. SQLite stays the zero-config default; nothing changes unless the URL is set. The Postgres schema mirrors SQLite's exactly — timestamps as RFC3339 text, JSON marshaled in the application — so every package-level scan/marshal helper is shared and only the SQL dialect (placeholders, the metadata JSON accessor) and the DDL differ. The existing SQLite backend is left untouched, so there's no risk to the crash-resume path it already powers. Forward-only migrations run on startup via embedded Goose with the same downgrade protection (refuse to start on a schema newer than the binary). A shared Store conformance suite runs against both backends to hold them at behavioral parity; it covers runs, steps, the cost ledger and its summaries (including metadata grouping), tool calls, memory facts, approvals, policy bundles, and checkpoints. Verified against a real Postgres: the conformance and downgrade-protection suites pass, and a daemon restart against shared Postgres state reloads an in-flight run and keeps enforcing its already-spent budget — crash-resume works across instances. The Postgres tests are skipped unless RISKKERNEL_TEST_DATABASE_URL points at a disposable database. Dependency: github.com/jackc/pgx/v5 (the standard Postgres driver, used via database/sql so the query layer stays shared with SQLite).
prashar32
force-pushed
the
feat/postgres-backend
branch
from
June 14, 2026 16:11
84948a4 to
74e5936
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SQLite is the right default — zero-config, a single file you own. This adds an
opt-in Postgres backend behind the same
Storeinterface for multi-instance /HA deployments, selected by setting
RISKKERNEL_DATABASE_URL. Nothing changesunless you set it.
Design
The Postgres schema mirrors SQLite's exactly — timestamps as RFC3339 text, JSON
marshaled in the application — so every package-level scan/marshal helper is
reused; only the SQL dialect (placeholder style, the metadata JSON accessor) and
the DDL differ. The existing SQLite backend is left completely untouched, so
there's zero risk to the crash-resume path it already powers.
protection (refuse to boot on a schema newer than the binary).
Store: runs, steps, the cost ledger and its summaries(including metadata grouping), tool-call audit trail, memory facts, approvals,
policy bundles, and crash-resumable checkpoints.
github.com/jackc/pgx/v5, used viadatabase/sqlso the query layerstays shared in style with SQLite. (+3 small transitive
jackc/*helpers.)Tests
Storeconformance suite (conformance_test.go) runs againstboth backends, so a query that works on one but not the other fails CI.
TestSQLiteConformanceruns in ordinary CI;TestPostgresConformance/TestPostgresMigrateDowngradeProtectionrun whenRISKKERNEL_TEST_DATABASE_URLpoints at a disposable Postgres (CI provides one as a service).
downgrade-protection test pass, and a daemon restart against shared Postgres
state reloaded an in-flight run and kept enforcing its already-spent budget —
crash-resume works across instances, not just on SQLite.
go test -race ./...green;go vet ./...clean;gofmtclean.Docs:
docs/POSTGRES.md; compatibility posture updated inCOMPATIBILITY.md(both schemas forward-migratable, parity held by the conformancesuite).
Closes #25