KB-5313

RS4A-06 — Interface F Deployed-Artifact Resolver v0.2 — 2026-06-21

8 min read Revision 1
rs4ainterface-fartifact-resolverv0.2hash-not-signaturefail-closeddesign-only2026-06-21

RS4A-06 — Interface F Deployed-Artifact Resolver v0.2 — 2026-06-21

Macro: RS4A · Mục tiêu F Deliverable: 06 of 14 · design-only (does NOT create any carrier/table/column) Builds on: RS3B-04 Interface F v0.1 (CARRIER_SOURCE_UNPROVEN_FAIL_CLOSED); promoted to v0.2 with live carrier reads (this macro) and a sharpened hash taxonomy. Gate: REGISTRATION_HOLD · REGISTRATION_CAN_PROCEED = NO Status: INTERFACE_F_FAIL_CLOSED — no live carrier proves a per-artifact, immutable, owner-bound deployed-artifact-hash binding. The resolver is specified; it emits nothing trusted today.


1. Five distinct hashes (the taxonomy that must never collapse)

The defect across prior cycles was treating different hashes as interchangeable. v0.2 pins five:

Hash What it is Trust value Source
request_proposed.artifact_hash the caller's claimed hash none — caller input, never authority RS4A-02 input
source mirror hash sha256 of the KB source mirror (registrar 31d5cf15…, catalog-sync 7dd84cda…) proves the mirror matches a recorded value; fidelity-of-record only (P1) RS3C-02
snapshot recorded hash wf_fs_dot_bin_snapshot.hash recorded same-day on the VPS (id 6022/5963) integrity record, not a signature, not a Codex-live attestation; mutable, no observer credential LIVE (this macro)
trusted deployed-artifact hash a hash a PROVEN carrier binds to (canonical_path, origin) under immutability + restricted writer + observer independence the only hash that may authorize a registration row does not exist today
trusted_attested.artifact_hash the resolver's output, emitted only if all R-criteria pass consumable by registrar/replay emitted by Interface F (none today)

Hard rule: hash ≠ signature. A matching hash proves content equality to a recorded value, not authenticity, authority, or freshness. The source mirror hash equalling the snapshot hash (P1) establishes the mirror is faithful to a same-day record — it does not establish a trusted deployed-artifact attestation.


2. Live carrier evidence (my own read-only reads, 2026-06-21)

Candidate carrier Live fact Verdict
dot_tools 309 rows, 28 cols, no hash/checksum/artifact_hash column (cols verified live) NOT_FIT (no carrier)
wf_fs_dot_bin_snapshot constraints = PK(id) + UNIQUE(source_key, object_key); no triggers; hash is a plain column (integrity record, mutable, no observer credential) SOURCE_UNPROVEN_FAIL_CLOSED — binds identity (source_key,object_key), not hash; no immutability; not a signature
context_pack_manifest 131 rows; columns include logical_checksum_sha256, file_checksum_sha256, git_commit, plus per-pack aggregate counts law_count, dot_count, entity_count, species_count, db_count, total_size_bytes, section_count; constraints = PK(id) + CHECKs (publish_status/kb_mirror_status/health_status/section_count>0) + FK trigger_source; no UNIQUE on either checksum; no immutability trigger STRONGEST_CANDIDATE_BUT_UNPROVEN_AND_NOT_PER_ARTIFACT — the checksums describe the whole context pack (aggregate), not one deployed DOT artifact; cannot bind one artifact's hash
dot_tools.extra_metadata (jsonb) caller-writable free-text NOT_FIT_AS_AUTHORITY (proposed tier only)

v0.2 sharpening vs v0.1: v0.1 named context_pack_manifest the "strongest candidate / lead". Live column inspection now shows its sha256 columns are per-pack aggregates (law_count/dot_count/...), not per-artifact — so even as the lead, it cannot carry a single DOT artifact's deployed hash. This is a stronger fail-closed than v0.1: there is no per-artifact hash carrier at all in live runtime (G4 confirmed live).


3. Deployed Artifact Resolver Contract v0.2 (criteria only)

resolve_deployed_artifact(request_proposed) -> trusted_attested.artifact_hash | FAIL_CLOSED
  Inputs (request_proposed, untrusted):
    artifact_path, artifact_hash, hash_algorithm, canonicalization_version, artifact_type, origin, admission_ref
  Required to emit trusted_attested.artifact_hash (ALL must pass):
    R1 canonical_path          : artifact_path normalized to one canonical deployed path (no symlink/alias/.. traversal)
    R2 hash_algorithm          : on a governed allowlist (e.g. sha256); UNKNOWN -> reject
    R3 canonicalization_version: declared + supported; mismatch -> reject
    R4 carrier_readback        : a PROVEN carrier row (NOT a caller copy) yields the hash for canonical_path@origin
    R5 origin_proof            : origin (path root / git_commit) matches the carrier row's origin
    R6 per_artifact_binding    : carrier row binds exactly ONE deployed artifact (not an aggregate manifest)
    R7 artifact_type_match     : declared artifact_type == admitted artifact type (closes D21 .ts-vs-bash)
    R8 admission_binding       : admission_ref proves this artifact is admitted (RS4A-02)
    R9 immutable_admission     : admission + carrier rows immutable/append-only for the replay horizon
    R10 drift_state            : carrier hash vs request_proposed.artifact_hash; == -> NONE; != -> HASH_MISMATCH (reject)
  Output (only if R1..R10 pass): trusted_attested.artifact_hash, canonical_path, origin, drift_state=NONE,
                                 source_carrier_ref, hash_algorithm, canonicalization_version, artifact_type
  Consumer readback rule: registrar (RS4A-02) and replay (RS4A-07) MUST reread trusted_attested.artifact_hash;
                          NEVER accept request_proposed.artifact_hash directly.
  Fail-closed: if any carrier/writer/readback/immutability is unproven, emit NOTHING in trusted_attested.* .

R6 is the v0.2 addition that closes the context_pack_manifest aggregate gap.


4. Negative cases

Case Input/state Expected Layer
F-N01 only request_proposed.artifact_hash, no proven carrier SOURCE_UNPROVEN_FAIL_CLOSED (no trusted output) F
F-N02 carrier hash ≠ proposed hash HASH_MISMATCH F
F-N03 snapshot hash used as authority CARRIER_NOT_SIGNATURE (integrity record ≠ attestation) F
F-N04 path is symlink / alias / .. traversal NON_CANONICAL_PATH (R1) V/F
F-N05 hash_algorithm not on allowlist UNKNOWN_HASH_ALGO (R2) V/F
F-N06 extra_metadata jsonb carries a hash treated as request_proposed, not attestation V/F
F-N07 context_pack_manifest checksum offered as the artifact hash CARRIER_NOT_PER_ARTIFACT (R6 — aggregate manifest) F
F-N08 .ts declared vs bash artifact ARTIFACT_TYPE_MISMATCH (R7) V/F
F-N09 carrier exists & parses, but no immutability / writer not enumerable trust NOT inferred from existence/parse → fail-closed (R9) F

5. Required future surface (to lift fail-closed)

A selected carrier must prove ALL: (1) governed restricted writer with enumerable grants; (2) immutability (UPDATE/DELETE-blocking trigger/constraint — none today on any candidate); (3) UNIQUE binding of (canonical_path, origin) → hash; (4) per-DOT-artifact linkage (not an aggregate manifest); (5) observer independence (producer ≠ caller; credential evidence, not a string label); (6) retention across rollback/retry. Reuse-first: harden an existing surface before any new ledger — no new table authorized.

6. Status

  • Interface F v0.2: INTERFACE_F_FAIL_CLOSED — sharper than v0.1: no per-artifact hash carrier exists (G4 live-confirmed).
  • Lead future candidate remains a context_pack_manifest-style row only if extended to per-artifact + UNIQUE + immutability + observer independence — UNPROVEN today.
  • Hash ≠ signature; caller path/hash ≠ authority; existence/parse ≠ trust. Gate REGISTRATION_HOLD · CAN_PROCEED = NO.