RS3B-04 — Deployed Artifact Resolver (Interface F) v0.1 — 2026-06-21
RS3B-04 — Deployed Artifact Resolver (Interface F) v0.1 — 2026-06-21
Macro: RS3B-REGISTRAR-HARDENING-DESIGN (read-only / KB-design)
Deliverable: 04 of 10 · Interface F deployed-artifact resolver (Mục tiêu D)
Date: 2026-06-21 · 0 mutations · NO_CODEX_LIVE_READ
Deliverable status: INTERFACE_F_CARRIER_SOURCE_UNPROVEN_FAIL_CLOSED — no runtime carrier proves a deployed-artifact-hash binding; the resolver is defined as criteria and remains fail-closed.
1. What interface F must do
Resolve, for one admitted artifact, a trusted deployed-artifact hash that the registrar (RS3B-03) and replay key (RS3B-05) can bind — distinguishing the caller's proposed values from a producer-attested value (RS3-PATCH2 §9). Hash is not a signature (must-not-do #26); caller-provided path/hash is not authority (#27).
request_proposed.{artifact_path, artifact_hash, hash_algorithm, canonicalization_version, origin}
│ (untrusted; never self-promotes)
▼
INTERFACE F resolver ──reads──> a PROVEN carrier row (writer/immutability/readback proven)
│
├─ produce trusted_attested.artifact_hash ONLY if carrier passes promotion criteria
└─ else FAIL_CLOSED (no trusted_attested.* emitted; consumer rejects)
2. Live carrier evidence (2026-06-21) and classification
| Candidate carrier | Live fact | Hash binding | Promotion gaps | Verdict |
|---|---|---|---|---|
dot_tools |
309 rows, 28 cols, no hash/artifact_hash/checksum column; extra_metadata jsonb exists |
none | no hash column at all | NOT_FIT (no carrier) |
wf_fs_dot_bin_snapshot |
289 rows; hash text NULLABLE; UNIQUE(source_key,object_key) binds identity not hash; no observer-credential/chronology; no triggers |
weak (nullable, unbound to run/attempt/owner) | writer unproven, hash nullable, no immutability, no run binding | SOURCE_UNPROVEN_FAIL_CLOSED (RS3-PATCH2: NOT_FIT_FOR_AUTHENTICITY as manifest) |
wf_fs_script_snapshot / wf_docker_container_snapshot |
42 / 11 rows; hash NULLABLE; same shape |
weak | same as above | SOURCE_UNPROVEN_FAIL_CLOSED |
context_pack_manifest |
131 rows; logical_checksum_sha256 NOT NULL + file_checksum_sha256 NOT NULL + git_commit NOT NULL + generated_at; no UNIQUE on checksum, no triggers, no observer-credential |
strongest (non-null sha256 + git_commit) | no UNIQUE binding, no immutability trigger, writer not enumerable, no per-DOT-artifact link proven, no observer independence | STRONGEST_CANDIDATE_BUT_UNPROVEN → fail-closed |
dot_tools.extra_metadata (jsonb) |
only extra_metadata-named column in schema |
could carry a hash string | jsonb is caller-writable free-text → request_proposed, not attestation; no immutability |
NOT_FIT_AS_AUTHORITY (proposed tier only) |
vps_deploy_log.env_hash, directus_versions.hash, various *.content_hash |
exist (see RS3B evidence) | bind other domains (deploy env, content versioning), not deployed DOT artifact | wrong subject; writer/immutability unproven | OUT_OF_DOMAIN |
No carrier proves all promotion criteria (proven restricted writer · immutability/append-only · consumer readback · non-null tamper evidence · retention · run/owner binding). context_pack_manifest is the only carrier with non-null sha256 checksums and is therefore the lead candidate for a future proven path — but today it fails UNIQUE-binding, immutability, observer-independence, and per-artifact linkage. Hence interface F is fail-closed.
3. Deployed Artifact Resolver Contract v0.1
resolve_deployed_artifact(request_proposed) -> trusted_attested.artifact_hash | FAIL_CLOSED
Inputs (request_proposed, untrusted):
artifact_path, artifact_hash, hash_algorithm, canonicalization_version, origin, admission_ref
Required to emit trusted_attested.artifact_hash (ALL):
R1 canonical_path : artifact_path normalized to a single canonical deployed path (no symlink/alias/traversal)
R2 hash_algorithm : from a governed allowlist (e.g. sha256); UNKNOWN -> reject
R3 canonicalization_version : declared + supported; mismatch -> reject
R4 carrier_readback : a PROVEN carrier row (NOT caller copy) yields the hash for canonical_path@origin
R5 origin_proof : origin (path root / git_commit) matches the carrier row's origin
R6 admission_binding : admission_ref proves this artifact is admitted (RS3B-03)
R7 immutable_admission_ref : the admission record is immutable/append-only for the replay horizon
R8 drift_state : compare carrier hash vs request_proposed.artifact_hash
== -> drift_state=NONE ; != -> HASH_MISMATCH (reject)
Output (only if R1..R8 pass): trusted_attested.artifact_hash, canonical_path, origin, drift_state=NONE,
source_carrier_ref, hash_algorithm, canonicalization_version
Consumer readback rule: registrar/replay MUST reread trusted_attested.artifact_hash from this resolver,
never accept request_proposed.artifact_hash directly.
Fail-closed: if any carrier/writer/readback is unproven, emit NOTHING in trusted_attested.* ; consumer rejects.
4. Negative cases
| Case | Input/state | Expected | Layer |
|---|---|---|---|
| F-N01 | only request_proposed.artifact_hash present, no proven carrier |
SOURCE_UNPROVEN_FAIL_CLOSED (no trusted output) |
F |
| F-N02 | carrier hash ≠ proposed hash | HASH_MISMATCH reject |
F |
| F-N03 | wf_fs_dot_bin_snapshot.hash is NULL for the path |
ARTIFACT_HASH_NULL → fail-closed |
F |
| F-N04 | path is a symlink/alias/.. traversal |
NON_CANONICAL_PATH reject (R1) |
V/F |
| F-N05 | hash_algorithm not on allowlist |
UNKNOWN_HASH_ALGO reject |
V/F |
| F-N06 | extra_metadata jsonb carries a hash |
treated as request_proposed, not attestation → reject if used as trusted |
V/F |
| F-N07 | admission record mutable / not found | ADMISSION_NOT_IMMUTABLE / ARTIFACT_NOT_ADMITTED |
R/F |
| F-N08 | carrier exists but writer not enumerable | CARRIER_WRITER_UNPROVEN → fail-closed |
F |
| F-N09 | row exists & parses, but no immutability | trust not inferred from existence/parse (RS3-PATCH2 §10) → fail-closed | F |
5. Required future surface (defined, not invented)
To lift INTERFACE_F_CARRIER_SOURCE_UNPROVEN_FAIL_CLOSED, the selected carrier (lead candidate: a context_pack_manifest-style row, reusing the existing non-null sha256 columns) must prove: (1) a governed restricted writer with enumerable grants; (2) immutability (UPDATE/DELETE-blocking trigger or constraint — none exists today); (3) a UNIQUE binding of (canonical_path, origin) → hash; (4) a per-DOT-artifact link so the registrar can resolve the one artifact; (5) observer independence (producer ≠ caller, credential evidence, not a string label); (6) retention across rollback/retry. No new ledger/table is authorized before these are evaluated against the existing carrier (reuse-first).
6. Status block
- Deliverable status:
INTERFACE_F_CARRIER_SOURCE_UNPROVEN_FAIL_CLOSED - Lead future candidate:
context_pack_manifest(non-null sha256) — UNPROVEN today - Hash ≠ signature; caller path/hash ≠ authority; existence/parse ≠ trust
- Registration gate:
REGISTRATION_HOLD·REGISTRATION_CAN_PROCEED = NO· 0 mutations