ruview @ v1227
integrity
- size
- 59.6 MiB
- downloaded
- last checked
release notes
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-levelverify()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
download
curl -fL -o v1227.zip https://ratatoskr.space/pkg/ruview/v1227.zip
printf '%s %s\n' 'f3e759709d68ba8a45711ed8c600d6f5e7d16a5562044e4c22dd23e099c923c8' 'v1227.zip' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/v1227.zip"
$out = "v1227.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "f3e759709d68ba8a45711ed8c600d6f5e7d16a5562044e4c22dd23e099c923c8") { throw "sha256 mismatch" }
curl -fL -o v1227.tar.gz https://ratatoskr.space/pkg/ruview/v1227.tar.gz
printf '%s %s\n' '3ac29a1597f43fcdb6c72b5338453dda5f8be036fcee3063f73d9613993ab706' 'v1227.tar.gz' | sha256sum -c -
$url = "https://ratatoskr.space/pkg/ruview/v1227.tar.gz"
$out = "v1227.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "3ac29a1597f43fcdb6c72b5338453dda5f8be036fcee3063f73d9613993ab706") { throw "sha256 mismatch" }
download via yggdrasil mesh
curl -fL -o v1227.zip http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.zip
printf '%s %s\n' 'f3e759709d68ba8a45711ed8c600d6f5e7d16a5562044e4c22dd23e099c923c8' 'v1227.zip' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.zip"
$out = "v1227.zip"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "f3e759709d68ba8a45711ed8c600d6f5e7d16a5562044e4c22dd23e099c923c8") { throw "sha256 mismatch" }
curl -fL -o v1227.tar.gz http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.tar.gz
printf '%s %s\n' '3ac29a1597f43fcdb6c72b5338453dda5f8be036fcee3063f73d9613993ab706' 'v1227.tar.gz' | sha256sum -c -
$url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.tar.gz"
$out = "v1227.tar.gz"
Invoke-WebRequest -Uri $url -OutFile $out
if ((Get-FileHash $out -Algorithm SHA256).Hash.ToLowerInvariant() -ne "3ac29a1597f43fcdb6c72b5338453dda5f8be036fcee3063f73d9613993ab706") { throw "sha256 mismatch" }
| artifact | format | size | hashes |
|---|---|---|---|
| v1227.zip | zip | 59.6 MiB |
blake3-24 4cd2b29d5b6f57e63e0c8c7fe873fc8eea7d238a9abfeca8
sha256 f3e759709d68ba8a45711ed8c600d6f5e7d16a5562044e4c22dd23e099c923c8
sha1 49d265c4d9c617187103bfdd1a7564ced9def404
|
| v1227.tar.gz | tar.gz | 58.1 MiB |
blake3-24 b577811195bde3b4f6599772a41cd49e0b7f7178f1029d45
sha256 3ac29a1597f43fcdb6c72b5338453dda5f8be036fcee3063f73d9613993ab706
sha1 422f95da547bbb8c5acfe62a4282aeea6285dd03
|
install
http_archive(
name = "ruview",
urls = ["https://ratatoskr.space/pkg/ruview/v1227.tar.gz"],
integrity = "sha256-OsKaFZf0P822xytTOEU92l+L4Db87jBj9z2WE5k6twY=",
strip_prefix = "ruview-v1227",
)
.url = "https://ratatoskr.space/pkg/ruview/v1227.tar.gz",
install via yggdrasil mesh
http_archive(
name = "ruview",
urls = ["http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.tar.gz"],
integrity = "sha256-OsKaFZf0P822xytTOEU92l+L4Db87jBj9z2WE5k6twY=",
strip_prefix = "ruview-v1227",
)
.url = "http://14cc7d57b5e70f679b851fe5b272ce17c70632ff4beb5b35ab64bc706b2485af.pk.ygg/pkg/ruview/v1227.tar.gz",