Skip to main content

Module chain_validator

Module chain_validator 

Source
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 integrityrecord[i].previous_record_digest == digest(record[i-1]), step_seq strictly +1, genesis previous_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_id never 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§

DegradedHop
A hop whose strict record decode failed but whose identity fields survived — the C7 marking.
RuleReport
One rule’s verdict on one segment.
SegmentReport
One operation’s chain, judged independently.
ValidationReport

Enums§

Verdict

Constants§

UNATTRIBUTED_SEGMENT
The pseudo-segment for degraded hops whose operation_id did 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.