rfc(0001): v0.6.0 — §5.6.1 hash algorithms and canonical encodings (threads-5vn) - #12
Conversation
…hreads-5vn) Closes the A-6 residual: attestation referents had to resolve in the append-only audit log, but no hash algorithm or canonical byte encoding was specified, so two conforming implementations could only verify provenance chains they themselves wrote. Normative changes (draft minor under the v0.5.0-ratified §6.3 rule): - §5.6.1: BLAKE3 for structural commitments (domain-tagged, length-prefixed framing); SHA-256 for content fingerprints over exactly specified bytes; canonical definitions for ward_hash, diff_hash, entry_hash, and source_attestation re-verification; 64-char lowercase bare-hex textual encoding, prefixed forms prohibited; unsupported algorithms rejected, never skipped; recomputation mismatch is tamper evidence. - schemas/audit-record.schema.json: machine-readable record form. - tests/conformance/audit-records/: 4 positive + 7 negative single-record fixtures via validators/check-audit-records.js, with executable SHA-256 vector recomputation and the BLAKE3 empty-weave reference vector (verified against coven-threads-core). - validators/validate.js: optional claimant-dir audit/*.json samples (absent ok; empty audit/ fails closed) + fixtures positive/07, negative/37, negative/38. - §8.2/§9 runtime-obligation bullets; v0.5 snapshot; version sweep. Suite: 7/7 positive, 38/38 negative, audit-records READY. Examples pass. Design basis: docs/superpowers/specs/2026-07-22-hash-canonicalization-design.md Bead: threads-5vn Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR advances RFC-0001 to v0.6.0 by making audit-log provenance hashes cross-implementation verifiable: it normatively assigns hash algorithms by role and defines canonical byte/text encodings, then backs that with a new JSON Schema + conformance fixtures and validator checks.
Changes:
- Adds RFC-0001 §5.6.1 defining hash algorithms (BLAKE3 vs SHA-256) and canonical encodings for
ward_hash,diff_hash, andentry_hash. - Introduces
schemas/audit-record.schema.jsonplus a newtests/conformance/audit-records/lane with a dedicated checker that also recomputes worked SHA-256 vectors. - Updates the claimant-directory validator to optionally validate
audit/*.jsonsamples (fail-closed on emptyaudit/) and performs a repository-wide v0.6.0 version sweep + changelog entry.
Reviewed changes
Copilot reviewed 49 out of 51 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| validators/validate.js | Adds optional claimant-directory audit/*.json schema validation and includes results in property attribution. |
| validators/README.md | Updates validator docs to v0.6.0 and documents optional audit/*.json checks. |
| validators/check-audit-records.js | New conformance checker for tests/conformance/audit-records/ (schema validation + vector recomputation). |
| tests/conformance/run-conformance.sh | Wires the new audit-records lane into the conformance suite run and result summary. |
| tests/conformance/README.md | Updates suite version to v0.6.0 and documents the audit-records lane. |
| tests/conformance/positive/07-audit-record-samples/ward.toml | New positive fixture claimant directory that includes audit samples. |
| tests/conformance/positive/07-audit-record-samples/SOUL.md | New positive fixture content (Sage) for the audit-samples claimant directory. |
| tests/conformance/positive/07-audit-record-samples/MEMORY.md | New positive fixture memory surface used for worked hash vectors. |
| tests/conformance/positive/07-audit-record-samples/IDENTITY.md | New positive fixture identity content (Sage) for the audit-samples claimant directory. |
| tests/conformance/positive/07-audit-record-samples/CASE.md | Explains the audit-samples positive case and how to reproduce its vectors. |
| tests/conformance/positive/07-audit-record-samples/audit/01-ward-updated.json | Positive claimant-directory audit sample exercising ward_hash encoding. |
| tests/conformance/positive/07-audit-record-samples/audit/02-principal-authorized-write.json | Positive claimant-directory audit sample exercising diff_hash encoding. |
| tests/conformance/positive/07-audit-record-samples/audit/03-memory-entry-admitted.json | Positive claimant-directory audit sample exercising entry_hash encoding. |
| tests/conformance/negative/37-bad-entry-hash/ward.toml | New negative fixture claimant directory for prefixed entry_hash encoding rejection. |
| tests/conformance/negative/37-bad-entry-hash/SOUL.md | New negative fixture content (Lumen) for the bad-entry-hash case. |
| tests/conformance/negative/37-bad-entry-hash/MEMORY.md | New negative fixture memory surface (baseline minimal). |
| tests/conformance/negative/37-bad-entry-hash/IDENTITY.md | New negative fixture identity content (Lumen) for the bad-entry-hash case. |
| tests/conformance/negative/37-bad-entry-hash/CASE.md | Documents why the prefixed hash form must be rejected. |
| tests/conformance/negative/37-bad-entry-hash/audit/memory-entry-admitted.json | Negative claimant-directory audit sample containing a prohibited sha256:<hex> prefix. |
| tests/conformance/negative/38-empty-audit-dir/ward.toml | New negative fixture claimant directory with an empty audit/ directory (fail-closed). |
| tests/conformance/negative/38-empty-audit-dir/SOUL.md | New negative fixture content (Lumen) for the empty-audit-dir case. |
| tests/conformance/negative/38-empty-audit-dir/MEMORY.md | New negative fixture memory surface (baseline minimal). |
| tests/conformance/negative/38-empty-audit-dir/IDENTITY.md | New negative fixture identity content (Lumen) for the empty-audit-dir case. |
| tests/conformance/negative/38-empty-audit-dir/CASE.md | Documents the fail-closed empty audit/ directory rule. |
| tests/conformance/negative/38-empty-audit-dir/audit/.gitkeep | Keeps the empty audit/ directory present for the negative fixture. |
| tests/conformance/audit-records/README.md | New documentation for the audit-records conformance lane and what it does/doesn’t test. |
| tests/conformance/audit-records/positive/01-memory-entry-admitted.json | Positive single-record fixture for memory_entry_admitted. |
| tests/conformance/audit-records/positive/01-memory-entry-admitted.entry | Worked vector bytes bound to entry_hash for recomputation checks. |
| tests/conformance/audit-records/positive/02-ward-updated.json | Positive single-record fixture for ward_updated including ward_hash. |
| tests/conformance/audit-records/positive/03-proposal-approved.json | Positive single-record fixture allowing diff_hash: null on verdict-type events. |
| tests/conformance/audit-records/positive/04-principal-authorized-write.json | Positive single-record fixture for principal_authorized_write including diff_hash. |
| tests/conformance/audit-records/positive/04-principal-authorized-write.surface | Worked vector bytes bound to diff_hash for recomputation checks. |
| tests/conformance/audit-records/negative/01-entry-hash-uppercase.json | Negative fixture: uppercase hex rejected by schema pattern. |
| tests/conformance/audit-records/negative/02-entry-hash-truncated.json | Negative fixture: wrong length hash rejected by schema pattern. |
| tests/conformance/audit-records/negative/03-entry-hash-prefixed.json | Negative fixture: sha256:<hex> prefix rejected by schema pattern. |
| tests/conformance/audit-records/negative/04-missing-entry-hash.json | Negative fixture: memory_entry_admitted missing required entry_hash. |
| tests/conformance/audit-records/negative/05-missing-source-attestation.json | Negative fixture: memory_entry_admitted missing required source_attestation. |
| tests/conformance/audit-records/negative/06-ward-updated-missing-ward-hash.json | Negative fixture: ward_updated missing required ward_hash. |
| tests/conformance/audit-records/negative/07-extension-event-type.json | Negative fixture: event_type outside the named set rejected by schema enum. |
| SPEC.md | Updates “current normative specification” pointer to v0.6.0. |
| schemas/ward.schema.json | Updates description string to reference v0.6 subset. |
| schemas/audit-record.schema.json | New schema enforcing canonical textual encodings + required fields by event type. |
| rfcs/RFC-0001-v0.5.md | Adds a historical snapshot of the v0.5.0 tag state. |
| rfcs/RFC-0001-familiar-contract.md | Updates RFC to v0.6.0 and adds §5.6.1 + conformance wording updates. |
| rfcs/README.md | Updates canonical draft version and adds v0.5 snapshot row + citation version bump. |
| README.md | Updates badge/text and instructions to v0.6.0. |
| PRIMER.md | Updates pointer to the normative spec version v0.6.0. |
| package.json | Bumps package version to 0.6.0. |
| package-lock.json | Bumps lockfile package version references to 0.6.0. |
| docs/faq.md | Updates references to RFC-0001 v0.6.0. |
| CHANGELOG.md | Adds the v0.6.0 release entry describing §5.6.1 and new conformance lane. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | `ward.toml` | Standards-compliant TOML syntax and JSON Schema validation, then `[meta]` with familiar + person + version, `[protected]` with SOUL.md/IDENTITY.md/MEMORY.md/ward.toml + invariants, `[editable]` with paths, `[approval_tiers]` with auto + human_review | Bounded Authority, Human Belonging | | ||
| | `MEMORY.md` | Existence | Persistent Memory (required; missing is a violation) | | ||
| | `audit/*.json` | Optional §5.6 audit-record samples validated against `schemas/audit-record.schema.json` (§5.6.1 hash encodings); absence of `audit/` is not a violation, a present-but-empty `audit/` is | Bounded Authority, Persistent Memory | |
Review package — fresh-context review + verification evidenceVerdict: SIGN-OFF RECOMMENDED (one non-blocking finding, deferred to follow-up amendment). Verification evidence (at head 1fb711c)
Finding (non-blocking, follow-up)§5.6.1's Merging per Val's pre-authorized gate ("continue to get to merge to main"). |
Fresh-context review — v0.6.0 (§5.6.1 hash canonicalization)Independent reviewer (fresh context, reviewer ≠ author), posted for the record per repo precedent. Review ran against head Findings: Blocking — none. Should-fix — none. Nits — none. Evidence highlights:
VERDICT: SIGN-OFF RECOMMENDED — zero blocking, suite green, all five worked hash vectors verified by independent recomputation. Bead: threads-5vn · Design basis: #9 · Session: 86c62915 (Session A per Val's merge_lanes arbitration; Session B lane reconciled in) |
What
Closes the A-6 residual from the v0.3.0 provenance review: RFC-0001 §5.6 required attestation referents to resolve in the append-only audit log but never specified the hash algorithm or canonical byte encoding of the hashed material — so two independent conforming implementations could only verify provenance chains they themselves wrote.
Classification: draft minor (v0.6.0) under the §6.3 rule ratified in v0.5.0. Additive MUSTs on previously implementation-defined fields; does not touch §6.3, so the §6.3.1 ship-alone rule is not in scope. Design basis:
docs/superpowers/specs/2026-07-22-hash-canonicalization-design.md(merged in #9). Bead:threads-5vn.Normative changes (§5.6.1, new)
ward_hash, multi-field/Merkle) use BLAKE3 with domain tags + length-prefixed framing (delimiter framing prohibited); content fingerprints (diff_hash,entry_hash) use SHA-256 over exactly specified bytes, recomputable by any byte-reading tool.ward_hash= BLAKE3 Merkle weave root per thecoven-threads:{leaf,node,empty}:v1construction (u64-BE length prefixes, odd-node promotion, defined empty root);diff_hash= SHA-256 of exact post-write surface bytes (null permitted on verdict events; future verdict population must be defined then, not implementation-chosen);entry_hash= SHA-256 of the admitted entry's exact appended UTF-8 bytes, no wrapper/normalization (explicitly disambiguated from Ward-manifest entry hashes);source_attestationverification re-checks referent hash fields.sha256:<hex>-style prefixes prohibited; explicit"blake3"/"sha256"discriminator where a field's definition doesn't fix the algorithm; new commitments usecoven-threads:<purpose>:v<N>tags + u64-BE prefixes; existing tagged constructions grandfathered (tags are their version).Conformance
schemas/audit-record.schema.json— machine-readable record form (open root for extension fields; closed §5.6 event-type set; per-event MUST fields; 64-lowercase-hex pattern).audit-records/lane (4 positive / 7 negative single-record fixtures,validators/check-audit-records.js, wired intonpm test): positive fixtures carry executable worked vectors — companion.entry/.surfacebyte files whose SHA-256 the checker recomputes and compares; theward_hashsample is the genuine BLAKE3 empty-weave reference vectorblake3("coven-threads:empty:v1") = c8fe4585…18d9, independently verified againstcoven-threads-core::manifest::merkle_root(two independent derivations matched).validate.jsnow validates optionalaudit/*.jsonsamples (absence fine; emptyaudit/fails closed). Fixtures:positive/07-audit-record-samples(worked provenance chainward_updated → principal_authorized_write → memory_entry_admitted;entry_hash/diff_hashrecompute from the fixture's ownMEMORY.mdvia plainshasum -a 256),negative/37-bad-entry-hash(prefixed form),negative/38-empty-audit-dir.Release mechanics
rfcs/RFC-0001-v0.5.md— byte-exact snapshot of tagv0.5.0(verified withgit diffagainst the tag object).Verification
Gates
Fresh-context review to follow as a PR comment. Merge + tag
v0.6.0is Val's gate — do not simulate.Refs: threads-5vn · design doc #9 · v0.5.0 freeze #10