Expand description
P7-S5 · the chain validator (P2 §5 rules C1–C4 + C7). Host-ops tooling — CI and incident triage run the same knife — never part of an SDK runtime path. P7-S5 · the chain validator, batch 1: rules C1–C4 with C7 degradation marking (P2 §5).
Host-ops tooling, not an SDK runtime path: CI gates and incident triage run the same knife,
and C3 needs the deterministic transition (re-plan), which only the core can perform. The CLI
half is src/bin/ds-chain-validator.rs; this module is the verdict logic.
Input is a journal prefix — a sequence of opaque record byte blobs. Records are grouped into per-operation chain segments and every segment is judged independently. Nothing here ever re-serializes a record: blobs pass through untouched, so a self-digest verdict is a verdict about the bytes the host durably wrote.
The rules, and where each one gets its teeth:
- C1 · chain integrity —
record[i].previous_record_digest == digest(record[i-1]),step_seqstrictly +1, genesisprevious_record_digest = None. Complete segments go through [verify_record_chain]; a segment with degraded hops falls back to checking every link whose digests survived. - C2 · input idempotency — one
input_idnever yields two different records: a retry must reach the same record. Grouped per operation (the idempotency key’s namespace). - C3 · causal closure — every record’s resolved effect must be reproducible by
re-planning the earlier records. This is the §12.2 restore ladder’s genesis leg
([
restore_operation] with no checkpoint): chain verify + deterministic re-plan + per-step record-digest comparison. It doubles as the re-plan determinism regression gate — the direct gate for 0.2.62-class “this binary does not reproduce the history it is resuming” incidents. If C1 failed, C3 reports degraded rather than re-reporting the same break. - C4 · task lineage — the journal-direct half: every
(task_id, attempt_id)launch pair appears at most once (the launch token is derived from that pair, so a repeated pair is a reused token), and a spawn resolution names an effect the same operation published at an earlier step. The parent chain itself is not journaled; it holds structurally under C3’s re-plan because an orphan spawn has no outstanding effect to resolve. The durable launch-token ledger lives in checkpoints — batch 2 territory. Both limits are named in [ValidationReport::deferred]. - C7 · degradation — an old-format hop (strict decode fails but the identity fields survive) degrades the checks that need the missing fields instead of failing them. A proven digest mismatch fails C1 even when identity fields survive; every degraded hop is marked on its segment’s report. A blob that is not a record at all counts as unparseable input, which is an exit-code-2 condition (“evidence insufficient”), never a violation.
Structs§
- Degraded
Hop - A hop whose strict record decode failed but whose identity fields survived — the C7 marking.
- Rule
Report - One rule’s verdict on one segment.
- Segment
Report - One operation’s chain, judged independently.
- Validation
Report
Enums§
Constants§
- UNATTRIBUTED_
SEGMENT - The pseudo-segment for degraded hops whose
operation_iddid not survive. Kept obviously synthetic so a report reader never confuses it with a real operation.
Functions§
- validate_
journal - Validate a journal prefix: a sequence of opaque record byte blobs, in any order. Records
group into per-operation segments, each judged independently; blob order never matters
because the chain’s own
step_seq/digest links define the order.