Skip to content

rfc(0001): v0.6.0 — §5.6.1 hash algorithms and canonical encodings (threads-5vn) - #12

Merged
BunsDev merged 1 commit into
mainfrom
rfc/v0.6.0-hash-canonicalization
Jul 26, 2026
Merged

rfc(0001): v0.6.0 — §5.6.1 hash algorithms and canonical encodings (threads-5vn)#12
BunsDev merged 1 commit into
mainfrom
rfc/v0.6.0-hash-canonicalization

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 26, 2026

Copy link
Copy Markdown
Member

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)

  • Algorithm assignment by role — structural commitments (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.
  • Canonical field definitionsward_hash = BLAKE3 Merkle weave root per the coven-threads:{leaf,node,empty}:v1 construction (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_attestation verification re-checks referent hash fields.
  • Encodings — raw 32 bytes in binary contexts; 64-char lowercase bare hex in textual contexts; sha256:<hex>-style prefixes prohibited; explicit "blake3"/"sha256" discriminator where a field's definition doesn't fix the algorithm; new commitments use coven-threads:<purpose>:v<N> tags + u64-BE prefixes; existing tagged constructions grandfathered (tags are their version).
  • Fail-closed + cross-implementation MUSTs — unsupported algorithm ⇒ reject, never skip; every recorded hash recomputable from log + surfaces regardless of writer; recomputation mismatch = tamper evidence.

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).
  • New audit-records/ lane (4 positive / 7 negative single-record fixtures, validators/check-audit-records.js, wired into npm test): positive fixtures carry executable worked vectors — companion .entry/.surface byte files whose SHA-256 the checker recomputes and compares; the ward_hash sample is the genuine BLAKE3 empty-weave reference vector blake3("coven-threads:empty:v1") = c8fe4585…18d9, independently verified against coven-threads-core::manifest::merkle_root (two independent derivations matched).
  • Claimant-directory lanevalidate.js now validates optional audit/*.json samples (absence fine; empty audit/ fails closed). Fixtures: positive/07-audit-record-samples (worked provenance chain ward_updated → principal_authorized_write → memory_entry_admitted; entry_hash/diff_hash recompute from the fixture's own MEMORY.md via plain shasum -a 256), negative/37-bad-entry-hash (prefixed form), negative/38-empty-audit-dir.
  • §8.2/§9 — runtime obligations documented: recomputation-as-tamper-evidence, fail-closed algorithm rejection, and non-empty-weave BLAKE3 verification remain integration-level.

Release mechanics

  • rfcs/RFC-0001-v0.5.md — byte-exact snapshot of tag v0.5.0 (verified with git diff against the tag object).
  • Version sweep to v0.6.0: README badge/text, PRIMER, SPEC, rfcs/README (index + snapshot table + citations), docs/faq, conformance + validator READMEs, validator banner, ward.schema description, package{,-lock}.json.
  • CHANGELOG.md + RFC §11 entries with the §6.3-required migration impact (none for the reference implementation — codifies deployed practice; existing directories unaffected) and security rationale.

Verification

npm test → positive 7/7, negative 38/38, audit-records READY (4+7), unexpected 0
npm run validate:examples → sage PASS, minimal PASS
snapshot: git show v0.5.0:rfcs/RFC-0001-familiar-contract.md ≡ rfcs/RFC-0001-v0.5.md (0-diff)
BLAKE3 vector: computed from coven-threads-core (path-dep harness) = fixture value
SHA-256 vectors: recomputed by checker at every suite run; fixture 07 vectors reproduce via shasum

Gates

Fresh-context review to follow as a PR comment. Merge + tag v0.6.0 is Val's gate — do not simulate.

Refs: threads-5vn · design doc #9 · v0.5.0 freeze #10

…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>
Copilot AI review requested due to automatic review settings July 26, 2026 08:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entry_hash.
  • Introduces schemas/audit-record.schema.json plus a new tests/conformance/audit-records/ lane with a dedicated checker that also recomputes worked SHA-256 vectors.
  • Updates the claimant-directory validator to optionally validate audit/*.json samples (fail-closed on empty audit/) 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.

Comment thread validators/README.md
Comment on lines 41 to +43
| `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 |
@BunsDev

BunsDev commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Review package — fresh-context review + verification evidence

Verdict: SIGN-OFF RECOMMENDED (one non-blocking finding, deferred to follow-up amendment).

Verification evidence (at head 1fb711c)

  • npm test: positive 7/7, negative 38/38, audit-records READY, unexpected 0 → READY
  • validate.js examples/sage + examples/minimal: PASS
  • Worked vectors independently recomputed: blake3("coven-threads:empty:v1") = c8fe4585…18d9 via independent b3sum (matches fixtures 02 + 07); all SHA-256 .entry/.surface companions and fixture 07's MEMORY.md full-file/last-line vectors match via shasum -a 256
  • Fixture 07 provenance chain coherent (03's source_attestation → 02's event_id, ascending timestamps)
  • Schema: draft-07 if/then blocks all carry required: ["event_type"] guards (no misfire); negative fixtures each fail for their documented reason
  • Lane wiring: audit-lane failure cannot escape run-conformance.sh exit 0 (unexpected → exit 1)
  • Snapshot rfcs/RFC-0001-v0.5.md byte-exact vs git show v0.5.0:rfcs/RFC-0001-familiar-contract.md (md5 241f832e…); source commit 6ab88f8 = git rev-parse v0.5.0^{commit}
  • Version sweep: no stale current-position v0.5.0 anchors
  • Governance: no §6.3 change → §6.3.1 ship-alone rule not triggered; draft-minor classification per ratified v0.5.0 rule
  • Design traceability: D-1 (algorithm-by-role) → §5.6.1 ¶1–2; D-2 (canonical fields) → §5.6.1 defs; D-3 (encoding) → §5.6.1 encoding ¶; D-4 (cross-impl verification) → §5.6.1 final ¶ + §8.2

Finding (non-blocking, follow-up)

§5.6.1's ward_hash construction names "per-thread leaf commitments" without defining the leaf payload (lives only in coven-threads-core/src/weave.rs::thread_leaf_bytes, thread:v2 framing), and the cross-impl recompute MUST overclaims its input set for ward_hash (preimage includes weave state absent from log + surface bytes; airtight for diff_hash/entry_hash, which is the actual A-6 closure). Inherited verbatim from approved design doc D-2/D-4; already fenced by this release's own §9 gap bullet. Fix vehicle: follow-up draft-minor restoring D-2's explicit reference-construction delegation and scoping the recompute MUST per hash role. Tracked as a coven-threads bead.

Merging per Val's pre-authorized gate ("continue to get to merge to main").

@BunsDev
BunsDev merged commit cade5a0 into main Jul 26, 2026
1 check passed
@BunsDev

BunsDev commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

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 1fb711c; PR merged mid-review as cade5a0 — reviewer verified cade5a0^{tree} == 1fb711c^{tree}, so findings apply verbatim to what merged.

Findings: Blocking — none. Should-fix — none. Nits — none.

Evidence highlights:

  • RFC text — §5.6.1 faithful to design D-1..D-4; RFC 2119 usage correct; §6.1 recomputation claim precisely scoped (BLAKE3 vector deliberately not claimed as suite-recomputed; §9 documents that gap); §6.3 semantics untouched (anchor-only edit per §6.3.1 carve-out); draft-minor classification correct with required migration impact + security rationale in both changelogs.
  • Snapshotrfcs/RFC-0001-v0.5.md byte-exact vs git show v0.5.0:… (SHA-256 match); snapshot-table citation tag v0.5.0 (main 6ab88f8) verified.
  • Schema — matches §5.6/§5.6.1 prose: 7 event types, per-event conditional requireds, anchored ^[0-9a-f]{64}$, nullable diff_hash, open root (extension fields pass).
  • Validators — claimant audit/ lane fails closed (file-not-dir, empty dir incl. .gitkeep-only); per-file attribution incl. Windows paths; no regression (7/7, 38/38). check-audit-records.js genuinely recomputes: reviewer mutated a companion .entry byte → checker failed with mismatch, exit 1 (restored).
  • Fixtures — every negative fails for exactly its CASE-documented reason (Ajv keywords verified per fixture); positive/07 provenance chain resolves.
  • Worked vectors — all independently recomputed by reviewer: blake3("coven-threads:empty:v1") = c8fe4585…18d9 via fresh b3sum install (third independent derivation; matches coven-threads-core manifest.rs:25-89/weave.rs:83 construction); both audit-records companions; fixture 07 entry_hash/diff_hash via shasum -a 256.
  • Version sweep — complete; remaining v0.5.0 mentions are exactly the intentional historical keeps.
  • Suite (reviewer-run)npm test: positive 7/7, negative 38/38, audit-records READY (4+7), unexpected 0, exit 0. validate:examples: sage PASS, minimal PASS.

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants