Durable state and run history¶
When --state-dir is supplied, a scan writes immutable canonical JSON records
and transactionally indexes their metadata in state.sqlite:
prc-state/
├── state.sqlite
├── artifacts/
│ └── sha256/ab/<artifact-sha256>
├── evidence/
│ └── ab/<evidence-id>.json
└── runs/
└── <run-id>.json
Native artifacts are immutable raw bytes addressed by their declared SHA-256. Before writing a payload, the store verifies that the run declares the same digest and byte count, recomputes the digest, and refuses a different payload at an existing path. Generic adapter artifact descriptors and deliberately ephemeral sensitive reports do not authorize payload persistence.
The JSON records are authoritative. SQLite is a query index that can be rebuilt from those content-addressed records; it never replaces evidence or changes an assessment. Indexing verifies every run and evidence identity against its canonical record before one transaction updates runs, results, fingerprinted findings, finding locations and evidence links, evidence metadata, inventory files, inventory facts, relationships, and the audit event.
Create private state¶
Scanner evidence can contain sensitive paths and findings. Keep state outside the target repository on a local filesystem and restrict it to the current user:
mkdir -m 0700 /safe/local/path/prc-state
./prc scan \
--target /path/to/project \
--catalog-root /path/to/production-readiness-checklist \
--state-dir /safe/local/path/prc-state \
--format json \
--exit-policy never
The scanner creates a missing state root with mode 0700 and the database with
mode 0600. It rejects a pre-existing state root accessible by group or other
users. Windows relies on platform access controls because POSIX mode bits are not
available.
The initial store uses a full-synchronous rollback journal, a five-second busy timeout, immediate write transactions, strict tables, and connection-level foreign-key enforcement. WAL is deliberately not enabled: SQLite documents that WAL requires all users to be on one host and does not work on network filesystems. A remote or shared filesystem is not a supported state location even with the rollback journal.
List indexed runs¶
./prc history list \
--state-dir /safe/local/path/prc-state \
--limit 20
Exact filters are available for --target-name, --profile, and
--terminal-state. JSON output conforms to prc.history/v0.1:
./prc history list \
--state-dir /safe/local/path/prc-state \
--target-name project \
--format json > history.json
Counts preserve distinct states: Pass, Fail, and unresolved/blocked results are never averaged into a score.
Load a canonical run¶
./prc history show \
--state-dir /safe/local/path/prc-state \
--format json \
<run-id>
history show obtains the record path from the index, rejects absolute,
traversing, or symlink-escaping paths, loads the immutable JSON, and recomputes
its run identity before returning it. A missing, modified, or mismatched record
is an error; the database is never treated as sufficient proof by itself.
The implementation enables foreign keys explicitly because SQLite does not
guarantee they are enabled by default, and its integrity audit uses both
PRAGMA integrity_check
and PRAGMA foreign_key_check.
Run both checks and obtain indexed record counts with:
./prc history check \
--state-dir /safe/local/path/prc-state \
--format json
A successful JSON response conforms to prc.state-check/v0.2. It includes a
separate finding count; the frozen v0.1 schema remains available for archived
outputs. Corruption or a
foreign-key violation is an error and never produces an integrity: ok report.
Use diff-aware evidence invalidation to compare one of these canonical runs to a current target without treating the SQLite index as assessment authority.