* fix(engine): length-prefix witness fields to close domain-separation collision
The BLAKE3 trust witness concatenated model_version, calibration_version,
and privacy_decision boundary-to-boundary, with the variable-length evidence
list lacking an explicit count. A string straddling a field boundary (e.g. a
per-room adapter id absorbing the leading bytes of the calibration epoch, or a
model_version absorbing a trailing evidence ref) collided with a different
trust decision — silently un-distinguishing two distinct privacy-relevant
inputs and defeating the ADR-137 tamper/drift audit guarantee. model_version
is operator-influenceable via the adapter id (ADR-150 §3.4), so the ambiguity
was reachable.
Fix: domain-tag the hash and length-prefix every field (8-byte LE length),
plus an explicit evidence count. Pinned by two fails-on-old tests:
witness_distinguishes_model_calibration_boundary and
witness_distinguishes_evidence_model_boundary.
Co-Authored-By: claude-flow <ruv@ruv.net>
* test(engine): pin privacy monotonicity, fail-closed boundaries; de-magic constants
Review hardening for the governed-trust cycle (no behavior change):
- forced_contradiction_never_relaxes_class: property test over all 5 privacy
modes proving a forced contradiction only ever raises the emitted class byte
(more restrictive) and a clean cycle emits exactly the base class — the
ADR-141/120 information-only-removed invariant.
- empty_cycle_fails_closed: a zero-frame cycle errors (fusion NoFrames),
emits no SemanticState, and does not advance the cycle counter.
- single_node_cycle_is_well_formed: characterizes the n=1 boundary (no mesh,
no directional, base class, witness still emitted) — documents single-node
sensing as a valid non-demoting mode, not a bypass.
- De-magicked the engine-construction literals (coherence accept gate, ADR-143
SLAM discovery + static-anchor thresholds) into named documented consts,
value-identical, pinned by engine_constants_match_prior_values.
Co-Authored-By: claude-flow <ruv@ruv.net>
* docs(engine-review): record witness domain-separation fix + monotonicity clean bill
CHANGELOG [Unreleased] Security entry and review notes appended to ADR-137
(witness domain-separation fix) and ADR-141 (privacy monotonicity confirmed
clean over all 5 modes, fail-closed boundaries pinned).
Co-Authored-By: claude-flow <ruv@ruv.net>
All 10 streaming-engine ADRs (136-145) carried Status: Proposed while each has a
concrete commit-pinned "Built -- tested building block" Implementation-Status note
(136: 11f89727f; 137: 4fa3847ac; 138: fc7674bde; 139: 521a012d8; 140: 169a355bd;
141: 7d88eb84c; 142: 1f8e180d6; 143: 2d4f3dea5; 144: b10bc2e9a; 145: 0f336b7d3),
each with a test count.
Flipped each to "Accepted — partial (built + tested building block; integration
glue pending — see Implementation Status, commit <hash>)". Honest "partial", not
full Accepted: the notes themselves state the blocks are tested+compiling but
"mostly not yet on the live 20 Hz path". 143 (v2 dataset-gated) and 144 (no UWB
radio in fleet) carry their specific residual gates inline.
Co-Authored-By: claude-flow <ruv@ruv.net>
Weaves the three framing points into every ADR in the series:
- skeleton/scaffolding (data contracts + trust/privacy/audit machinery +
algorithms; real, tested, compiling) that existing sensing code plugs into
- Built (tested building block) vs Integration glue (not yet on the live 20 Hz
path) — per-ADR, with commit + issue references
- trust throughline (traceable evidence, sensor agreement, calibration
provenance, auditable privacy)
ADR-136 §8 carries the full series framing; 137-146 carry per-ADR status.
Co-Authored-By: claude-flow <ruv@ruv.net>