meetLab/ Docs/ REF · 08 — hash unification

Hash unification.

For most of SHCL-v2's lifetime the chain executor stamped "algorithm": "blake3" on entries while the verifier computed hashlib.sha256 against them. Every valid chain entry mismatched on every check. This document records the fix: BLAKE3 is now the sole authoritative chain-hash algorithm; SHA-256 survives only as a legacy artifact-seal fallback for seals minted before 2026-04-10.

StatusDecided · 2026-04-10
DocREF · 08 / 12
Sourcearchitecture/
hash_unification.md
ClosesREAL-BLOCKER-1
SAIRP_REMEDIATION_
PLAN_v2.md
GovernanceTier 2 · behavioral
I.

Decision

BLAKE3 is the sole authoritative hash algorithm for SHCL-v2 chain integrity.

SHA-256 is retained as a parallel content fingerprint in the SHCL codec (src/shcl/shcl_codec.py) and is supported as a backward-compatible fallback in memory seal verification for seals generated before 2026-04-10. It must not be used for chain-hash computation in any new code.

scope
Two enforcement surfaces change behavior: runtime/ledger/verify_shcl_chain.py (chain-integrity verification) and orchestration/scripts/governance/verify_memory_seal.py (artifact-hash verification inside memory seals). Everything else is unaffected.
II.

Background — the latent defect

The SHCL-v2 codec at src/shcl/shcl_codec.py has always used BLAKE3 as the primary chain hash:

# line 89
chain_hash = blake3.blake3(compressed_bytes).hexdigest()

# line 188
blake3.blake3(preimage).hexdigest()  # node_id

Meanwhile, runtime/ledger/verify_shcl_chain.py computed chain hashes with hashlib.sha256, then passed "algorithm": "blake3" into enforce(). The HALT-G211 chain-integrity predicate therefore compared a SHA-256-computed hash against a stored BLAKE3 hash, guaranteeing a mismatch on every valid chain entry.

discovery
Identified as a live defect via the SAIRP NotebookLM transcript review. ChatGPT flagged the dual-hash coexistence as a "direct invariant break"; the Human Relay applied a BLAKE3-only fix to the chain executor, but verify_shcl_chain.py was not updated at that time. This change closes that gap.
III.

Changes · verify_shcl_chain.py

_canonical_hash(entry, hash_key) now uses blake3.blake3 instead of hashlib.sha256. The hashlib import was removed. The file now correctly computes the BLAKE3 hash it claims to compute when calling enforce_or_raise() with "algorithm": "blake3".

AspectBeforeAfter
Hash function in _canonical_hashhashlib.sha256blake3.blake3
Algorithm passed to enforce()"blake3""blake3"
Match against stored chain hashguaranteed mismatchmatches when chain is intact
hashlib importpresentremoved
IV.

Changes · verify_memory_seal.py

Added _blake3_hash(path) alongside the retained _sha256(path). Artifact-hash comparison now follows a strict precedence:

#ConditionActionalgo_used
1seal entry has blake3 keycompute BLAKE3, compare"blake3"
2seal entry has sha256 key (no blake3)compute SHA-256, compare · legacy fallback for seals before 2026-04-10"sha256"
3neither key presentno hash check performed

The artifact_hash_mismatch finding now includes an algorithm field so downstream tooling can tell which algorithm produced the mismatch.

V.

Seal generation · new seals

Any seal-generating code — scripts/envelope/mint_ack_envelope.py, scripts/crypto_fabric/seal/ — that writes artifact hashes into a seal must write them under the blake3 key:

{
  "file": "runtime/governance/enforcement_engine.py",
  "blake3": "<64-char blake3 hex digest>"
}
do not write sha256 in new seals
The sha256 field is legacy-only. New seals carry blake3 exclusively. The verifier's precedence ladder (§ IV) means a seal with both keys present will be checked under blake3 only, but emitting both is needless surface — write blake3 alone.
VI.

SHCL codec · the surviving SHA-256 field

src/shcl/shcl_codec.py computes:

  • content_fingerprint — SHA-256, retained as a parallel interoperability field
  • chain_hash — BLAKE3, the authoritative chain-integrity hash

The SHA-256 content_fingerprint is not consumed by any enforcement predicate and has no authority role. It may be deprecated in a future Tier 3 change.

authority vs interoperability
BLAKE3 carries chain authority. SHA-256 lingers only where third-party tooling expects it (content fingerprint) or where seals predate the cutover (legacy fallback). No enforcement predicate reads SHA-256 in new code.
VII.

Test coverage

tests/governance/test_hash_unification.py verifies:

  • _canonical_hash() produces BLAKE3, not SHA-256
  • chain validation passes on a BLAKE3-hashed ledger
  • chain validation detects tampered hashes and broken linkage
  • memory-seal verification uses the blake3 key when present
  • memory-seal verification falls back to the sha256 key for legacy seals
  • the blake3 key takes precedence when both keys are present
chain hash entry _canonical_hash · blake3 compare to stored chain_hash PASS | HALT-G211 mismatch
doc · 08 · build 2026-04-25 event → enforce(event) → invariant → PASS | HALT meetLab · 2026