Add durable run persistence behind a RunRepository port (Epic 2) - #13
Merged
Conversation
Replace the MVP in-memory run registry with a port + adapters so run state can be durable, auditable, and multi-worker-ready — without changing any runtime authority rule. A repository only stores/retrieves runs; the verifier and gates still decide PASS/FAIL/BLOCKED. - RunRepository port (add/save/get/list); routers now call save() after every mutation so out-of-process stores stay durable. - InMemoryRunRepository: default for dev/tests; kept as `RunRegistry` alias with a public `.runs` dict for back-compat (existing tests unchanged). - PostgresRunRepository: persists each run as an authoritative JSON snapshot (lossless round-trip) and projects queryable audit rows (handler_results, gate_results, verifier_decisions). psycopg is an optional, lazily-imported dependency (requirements-postgres.txt); core install/tests need no DB. - Durable schema sql/0001_init.sql (idempotent): runs, run_attempts, handler_results, gate_results, verifier_decisions, evidence_artifacts. tenant_id reserved for Epic 5; run_attempts/evidence_artifacts defined for Epics 3/6. - Adapter selected at startup from AGENT_ANALYSIS_DATABASE_URL (in-memory default). - Tests: serialization round-trip (no DB) + repository contract parametrized over in-memory (always) and Postgres (when AGENT_ANALYSIS_TEST_DATABASE_URL is set) + Postgres-only restart-survival and projection tests. Verification: 262 passed, 6 skipped (default, no DB); 268 passed, 0 skipped against a real PostgreSQL. No merge/deploy/force-pass endpoint added; no gate weakened. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JQW4FXw46KBvMCVc2EduXT
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4666b67e46
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…dapter
PostgresRunRepository.save derived runs.final_status from
chain_execution_result.final_status but runs.verifier_decision from
verifier_report.decision when a report existed. After POST /runs/{id}/verify
this could persist skewed rows (final_status=PASS, verifier_decision=FAIL).
Derive both columns from a single source of truth: the verifier report when
present (both columns = report.decision), otherwise the chain execution result.
No verifier/gate logic or API route changed.
Adds Postgres-gated regression test
test_verifier_report_overrides_chain_final_status[FAIL|BLOCKED]: a run with
chain final_status=PASS, re-saved with verifier_report.decision FAIL/BLOCKED,
persists both runs columns as FAIL/BLOCKED.
Verification: default 262 passed, 8 skipped; PostgreSQL 270 passed, 0 skipped;
git diff --check clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQW4FXw46KBvMCVc2EduXT
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.
Epic 2 — Durable Run and Evidence Persistence
Replaces the MVP in-memory run registry with a port + adapters so run state can be durable, auditable, and multi-worker-ready — without changing any runtime authority rule. A repository only stores/retrieves runs; the verifier and gates still decide PASS/FAIL/BLOCKED.
Acceptance criteria — all met
RunRepositoryABC)RunRegistryalias preserved)Changes
RunRepository(add/save/get/list). Routers callsave()after every state/verifier/result mutation so out-of-process stores stay durable.InMemoryRunRepository, default for dev/tests; kept asRunRegistrywith public.runsfor back-compat (existing tests unchanged).PostgresRunRepository: authoritative JSON snapshot (lossless round-trip) + projected audit rows (handler_results,gate_results,verifier_decisions).psycopgis an optional, lazily-imported dependency (requirements-postgres.txt); core install/tests need no DB.storage/sql/0001_init.sql(idempotent):runs,run_attempts,handler_results,gate_results,verifier_decisions,evidence_artifacts.tenant_idreserved for Epic 5;run_attempts/evidence_artifactsdefined for Epics 3/6.AGENT_ANALYSIS_DATABASE_URL(in-memory default).docs/persistence.md; README updated (status, layout, test counts).Verification
Scope honesty
run_attempts(Epic 3) andevidence_artifacts(Epic 6) are defined in the schema but populated by their own epics. No later epic was started in this PR. Merge remains human-controlled.🤖 Generated with Claude Code
Generated by Claude Code