RS5A-06 — register_dot APR Action Contract v1 — 2026-06-21
RS5A-06 — register_dot APR Action Contract v1 — 2026-06-21
Macro: RS5A · Mục tiêu E · Deliverable: 06 of 15 · design-only.
Status: REGISTER_DOT_ACTION_REQUIRED_NOT_PRESENT — register_dot is absent from apr_action_types ([[rs5a-02]] §4). This file defines the action contract; it does not create the action type, and creating it remains an Owner/governance act.
1. Action header
| field | value | rationale / live constraint |
|---|---|---|
action_code |
register_dot |
must be unique PK in apr_action_types |
action_domain |
dot_registration |
new domain; distinct from execution (DOT run) |
risk_level |
high |
matches register-shaped peers register_axis/register_topic_node (both high); ⇒ quorum president≥1 AND ai_council≥2 |
handler_ref |
dot-dot-register:governed (proposed) |
MUST NOT be unimplemented to apply; until wired, apply is fail-closed by fn_apr_block_unimplemented_handler |
status |
active (when authored) |
CHECK {active,deprecated,retired} |
2. Required bindings (admission preconditions — all conjunctive)
| obligation | binds to | current substrate gap |
|---|---|---|
required_owner_scope |
active accountable head for DOT_REGISTRATION_AUTHORITY ([[rs5a-04]]) |
scope + head absent ⇒ OWNER_OF_RECORD_ABSENT |
required_effect_identity |
PATCH2 effect_identity = H(protocol_version, operation="register_dot", canonical_target_dot_code, canonical_artifact_identity, canonical_artifact_hash) — business-only |
not reopened; consumed as-is |
required_authorization_nonce |
single-use nonce issued by the authority (issuer ∈ accountable/delegated head), bound to the attempt record | no nonce surface today |
required_artifact_binding |
canonical_artifact_hash carrier (DOT_HASH_CARRIER) |
no artifact-hash column on dot_tools / APR ⇒ ARTIFACT_HASH_CARRIER_UNPROVEN |
required_quorum |
quorum_passed(code)=true for risk=high AND approval bound to this effect_identity |
quorum does not bind effect ([[rs5a-08]]) |
required_authorization_binding_digest |
PATCH2 authorization_binding_digest (separate from U1) — see [[rs5a-07]] |
new envelope; not in U1 |
required_u3_head_policy |
PATCH2 U3 UNIQUE(code) WHERE lifecycle_role='current_head' across {draft,active} |
U3 surface REQUIRED_NOT_PRESENT |
required_status_policy |
writes inert status='draft' only (PATCH1) |
status domain not DB-enforced |
required_failure_audit |
failure-only audit row, separate txn (PATCH2-04) | sink unproven |
required_output |
one draft registration + effect_identity + authorization_binding_digest + audit refs; no activation |
— |
3. Reject codes (fail-closed; reused by [[rs5a-09]])
REGISTER_DOT_ACTION_REQUIRED_NOT_PRESENT · OWNER_OF_RECORD_ABSENT · ACCOUNTABLE_HEAD_UNRESOLVED · OWNER_SCOPE_MISMATCH · AUTHORITY_BINDING_UNRESOLVED · AUTHORIZATION_CHANGED_SAME_EFFECT_DUPLICATE · APPROVAL_NOT_BOUND_TO_EFFECT_IDENTITY · APPROVAL_BOUND_TO_REQUEST_PROPOSED_HASH · QUORUM_NOT_SATISFIED · QUORUM_EFFECT_BINDING_MISSING · QUORUM_APPROVER_IDENTITY_UNVERIFIED · APPROVAL_AFTER_ARTIFACT_HASH_DRIFT · AUTHORIZATION_WINDOW_EXPIRED · NONCE_ISSUER_NOT_AUTHORITY · WRONG_ACTION_FOR_EFFECT · ARTIFACT_HASH_CARRIER_UNPROVEN · STATUS_POLICY_UNDECLARED · U3_HEAD_POLICY_UNDECLARED · FAILURE_AUDIT_POLICY_UNDECLARED · CALLER_SELF_ASSERTED_OWNER_REJECTED · FREE_TEXT_OWNER_REJECTED · DIRECTUS_ROLE_NOT_GOVERNANCE_OWNER · OPERATOR_NOT_OWNER · HANDLER_UNIMPLEMENTED_RESERVE_ONLY.
4. Action family — separation (register_dot must NOT auto-activate)
| action | decides | writes | distinct from register_dot |
|---|---|---|---|
register_dot |
admit a new DOT registration | status='draft' registration + effect/authz digests |
base case |
activate_dot |
move draft → active (triggers notify) |
status transition | separate authority DOT_ACTIVATION_AUTHORITY; never implicit from registration |
supersede_dot_registration |
retire a head, promote a successor | U3 head swap | touches DOT_HEAD_UNIQUENESS; needs explicit authority |
register_dot_revision |
new artifact hash for same target code | new effect_identity (hash differs) | a different effect, not a duplicate |
dry_run_scan |
classify/scan only (the reusable RS4A classify_*) |
nothing | no authority needed; pure read; never writes |
Hard rule: register_dot produces an inert draft and stops. Activation is a separate action under a separate scope (this is precisely the unsafe "register ⇒ active" path RS4A rejected).