Automated release from CI pipeline
Changes:
cog-ha-matter (ADR-116 P4): witness file persistence + chain-level verify
Closes the witness audit-bundle surface. The hash-chain primitive
-
JSONL serializer from earlier iters only handled one event at a
time; this lands the file-stream surface that operations actually
need:WitnessChain::write_jsonl(&mut impl Write) -> io::Result<()>
— streams every event as one line +\n, empty chain writes
zero bytesWitnessChain::read_jsonl(impl BufRead) -> Result<WitnessChain, WitnessReadError>— parses event-by-event AND runs chain-level
verify()on the loaded chain, catching reordered or replayed
prefixes that per-event hashing alone misses
Critical security property: read_jsonl calls WitnessChain::verify
on the loaded chain BEFORE returning Ok. A forged bundle assembled
from two valid chains pasted together would slip past the
per-event hash check (each event's this_hash is internally
consistent) but the cross-event prev_hash linkage detects the
seam. Test read_jsonl_chain_verify_catches_reordered_events
locks this — swap two events in a 2-event bundle, see Verify error.
Error surface (new WitnessReadError enum):
Io { line_no, msg }— read failure mid-streamParse { line_no, source }— per-event from_jsonl_line failureVerify { source }— chain-level verify failure
line_no is 1-indexed so an auditor sees the same number their
text editor shows. Blank lines tolerated for hand-edited bundles.
7 new tests:
- empty chain writes zero bytes
- write→read round-trips a 3-event chain
- exactly N newlines for N events; trailing newline present
- blank lines / leading newline tolerated
- parse error surfaces with correct line_no
- reordered events caught by chain-level verify
- no-trailing-newline still loads the final event
51/51 cog tests green (44 → 51).
Co-Authored-By: claude-flow ruv@ruv.net
Docker Image:
ghcr.io/ruvnet/RuView:1f5b7b48c9160da6e1b1d62465fd3f542ace73ed