RS3B-03 — Single-Artifact Governed Registrar Contract v0.1 — 2026-06-21
RS3B-03 — Single-Artifact Governed Registrar Contract v0.1 — 2026-06-21
Macro: RS3B-REGISTRAR-HARDENING-DESIGN (read-only / KB-design)
Deliverable: 03 of 10 · Single-artifact registrar contract (Mục tiêu C)
Date: 2026-06-21 · 0 mutations · NO_CODEX_LIVE_READ
Deliverable status: CONTRACT_CRITERIA_DEFINED_PENDING_SOURCE — this is a target hardening contract; it cannot be reconciled against the registrar's real input/transaction shape until RS3B-01 source is read. No implementation.
1. Design intent
Harden the existing registrar (DOT-REGISTER / dot-dot-register) so a single invocation registers exactly one admitted artifact — never a broad scan, never "all untracked bin/dot-*." The contract is a pure dict/envelope contract in the style proven by the governed DOT_R2_B2_STAGING_SCHEMA_SHELL package (Option B: one primary identity + separable, independently-testable guards joined only by an explicit contract). It registers; it does not activate (activation is a separate Owner-gated step — RS3B-08, §4).
This is reuse-first hardening, not a new registrar: the target surface stays dot_tools (309 rows, live); no new registry/table/collection is introduced.
2. Input schema (registrar_request)
All fields required unless noted. Every field on the caller side is request_proposed.* (untrusted) per RS3-PATCH2 §9; the contract promotes a value only after a reread trusted_attested.* row agrees (RS3B-04, RS3B-05).
| Field | Tier | Meaning / binding | Reject if absent/invalid |
|---|---|---|---|
dot_code |
proposed | the single DOT code to register (one, not a set) | MISSING_DOT_CODE |
artifact_path |
proposed | canonical path of the one admitted artifact | MISSING_ARTIFACT_PATH |
admission_ref |
proposed | KB ref of the birth-admission record (e.g. …-birth-admission-…md) |
MISSING_ADMISSION_REF / ARTIFACT_NOT_ADMITTED |
artifact_hash |
proposed | claimed deployed-artifact hash | MISSING_ARTIFACT_HASH (resolved/verified by interface F → RS3B-04) |
hash_algorithm + canonicalization_version |
proposed | how artifact_hash was computed |
MISSING_HASH_ALGO / UNKNOWN_CANONICALIZATION |
origin |
proposed | deployed origin (path root / commit) | MISSING_ORIGIN |
owner_envelope_ref |
proposed | ref into governance_object_ownership head row |
OWNER_ABSENT (live: 0 rows → fail-closed today) |
approval_envelope_ref |
proposed | APR ref + quorum proof binding the artifact | APR_NOT_BOUND_TO_ARTIFACT (live: no register_dot action → fail-closed) |
logical_request_key |
proposed | stable per intended registration effect (RS3B-05 C1) | MISSING_LOGICAL_KEY |
authorization_nonce |
proposed | single-use authority credential, bound to envelope+window (RS3B-05 C1) | MISSING_NONCE / NONCE_UNBOUND |
attempt_id |
proposed | execution/retry identity; never part of single-use key | MISSING_ATTEMPT_ID |
run_id |
proposed | validated registration run id | BAD_RUN_ID |
closed_config_assertion |
proposed | asserts registration does not open any gate | WOULD_OPEN_GATE |
pair_cardinality_claim |
proposed | content-derived pair shape (RS3B-07), not "5" | PAIR_GUARD_MISMATCH |
owner_real_run_gate_open |
separate authority arg (not in dict) | boolean True only; registration must run with this closed |
ACTIVATION_AT_REGISTRATION if used to activate |
Broad-scan prohibition (hard): the contract accepts a scalar dot_code + artifact_path. A list/glob/"all untracked" input is a categorical reject MASS_REGISTRATION_ATTEMPTED. There is no scan mode.
3. Output schema (registrar_result)
{
decision: "REGISTER_CANDIDATE" | "REJECT" | "HOLD",
dot_code, logical_request_key, attempt_id, run_id,
reject_codes: [ ... ], # empty iff decision != REJECT
registered_row_intent: { table: "dot_tools", columns: {...}, status: "<closed, NOT active>" } | null,
postcondition_verifier_ref, # RS3B paired-verifier (DOT-HEALTH-DOT family)
audit_envelope: { sink: "<RS3B-06 selection>", payload_classification, written: bool },
activation: "NOT_PERFORMED" # always; activation is separate + Owner-gated
}
registered_row_intent is write-intent data only in this design package (no DB call is made by RS3B). The real registrar would, when hardened, perform the write inside the atomic boundary of RS3B-05 Phase-1.
4. Reject codes (complete set)
| Code | Trigger | Layer |
|---|---|---|
MASS_REGISTRATION_ATTEMPTED |
input is a set/glob/all-untracked | V (validator) |
ARTIFACT_NOT_ADMITTED |
admission_ref missing/invalid or not candidate-born/engineering-admitted |
V + R |
SOURCE_NOT_DEPLOYED |
artifact path not proven deployed (interface F) | F |
HASH_MISMATCH |
reread trusted_attested.artifact_hash ≠ request_proposed.artifact_hash |
F |
OWNER_ABSENT |
no governance_object_ownership head row (live: 0 rows) |
R/F |
APR_NOT_BOUND_TO_ARTIFACT |
approval not bound to this artifact_hash (live: no register_dot) |
R/F |
REPLAY_DUPLICATE |
logical_request_key already consumed (RS3B-05) |
R |
ATTEMPT_COLLISION |
concurrent attempt_id on same logical key |
R |
REPLAY_ATTEMPT_NO_BYPASS |
attempt identity used to re-admit same logical effect | R |
CATALOG_SYNC_CONFLICT |
catalog-sync wrote/raced same code (RS3B-02) |
R |
DOT_TOOLS_ROW_DRIFT |
existing dot_tools row diverges from admitted artifact |
R |
PAIR_GUARD_MISMATCH |
guard set not content-derivable / guard executable standalone (RS3B-07) | V/R |
WOULD_OPEN_GATE / ACTIVATION_AT_REGISTRATION |
registration would set status=active / open dot_config/runtime gate |
R |
AUDIT_SINK_UNAVAILABLE |
durable failure-audit sink not writable (RS3B-06) | R |
REQUEST_PROPOSED_AS_TRUSTED |
a proposed value was used without a matching reread trusted row | V/F |
5. Postcondition verifier
The registrar is paired with DOT-HEALTH-DOT (live paired_dot). RS3B requires a post-commit paired verifier (the register + verify reuse precedent: dot-apr-types-register/-audit, DOT-TAC-COLLECTION-REGISTER/-VERIFY) that, after the registration row commits, reads it back and proves: (a) exactly one row for dot_code exists; (b) its metadata matches the admitted artifact + trusted_attested.artifact_hash; (c) status is not an activating value; (d) the audit envelope was durably written. Verifier failure → POST_COMMIT_VERIFY_FAIL → compensating state (RS3B-05 C2 case 3), never silent.
6. No-activation guarantee
Registration commits a closed/inert row. It MUST NOT: set status=active for a watch-tier DOT (would trip trg_context_pack_dot_register notify → RS3B-08), flip any dot_config gate (process_dot_runtime.real_run, iu_core.operator_runtime), or wire dot_agent_api_contract. Activation is a separate, Owner-gated phase consuming a distinct authority nonce.
7. Status block
- Deliverable status:
CONTRACT_CRITERIA_DEFINED_PENDING_SOURCE - Depends on: RS3B-01 (source, HELD), RS3B-04 (interface F), RS3B-05 (replay), RS3B-06 (audit sink), RS3B-07 (pair/guard), RS3B-08 (triggers)
- Registration gate:
REGISTRATION_HOLD·REGISTRATION_CAN_PROCEED = NO· no new registry/table · 0 mutations