KB-5119

RS5A-08 — Quorum and Approval Proof Obligations — 2026-06-21

4 min read Revision 1
rs5ag2quorumproof-obligationsapproval-bindingfail-closed2026-06-21

RS5A-08 — Quorum and Approval Proof Obligations — 2026-06-21

Macro: RS5A · Mục tiêu G · Deliverable: 08 of 15. Method: function bodies obtained via pg_get_functiondef this macro (truncated=false). Quorum semantics are READ, not unproven. This file separates what quorum proves from what register_dot additionally requires.

1. Quorum function inventory (live)

function kind args body read? role
quorum_passed(text) function → boolean, STABLE 1 (p_code) yes callable quorum predicate
fn_apr_quorum_check() trigger 0 yes enforces quorum on pending→approved
fn_apr_block_unimplemented_handler() trigger 0 yes re-proves quorum + blocks unimplemented at →applied
fn_enforce_apr_lifecycle() trigger 0 inventoried (lifecycle FSM on status) status transition guard
fn_auto_approve_add() trigger 0 yes auto-approve disabled (P0 2026-06-06)

2. What quorum actually checks (from the body)

  1. resolves risk_level from apr_action_types via the request's proposed_action_code;
  2. counts apr_approvals: total approve, president (approver ILIKE '%president%'), ai_council, reject;
  3. excludes the proposer (source_context->>'proposer'|'created_by');
  4. any reject ⇒ false;
  5. tier gate: high ⇒ president≥1 ∧ council≥2, medium ⇒ president≥1, low ⇒ total≥1;
  6. returns false if request missing, proposed_action_code NULL, or risk unknown (fail-closed on NULL action).

3. Proof-obligation table (for register_dot, risk=high)

# obligation current evidence gap reject if missing future surface needed
Q1 a quorum predicate exists & is enforced quorum_passed + 2 triggers (read) QUORUM_NOT_SATISFIED
Q2 register_dot has a risk_level to gate on action absent register_dot ∉ apr_action_types REGISTER_DOT_ACTION_REQUIRED_NOT_PRESENT author action (Owner)
Q3 approval is bound to the exact effect_identity none — no effect/artifact column on APR/votes quorum counts votes, not effect APPROVAL_NOT_BOUND_TO_EFFECT_IDENTITY / QUORUM_EFFECT_BINDING_MISSING effect-bound approval column / authorization envelope ref ([[rs5a-07]])
Q4 approver identity is a governance head, not text fail-openapprover ILIKE '%president%' president = substring match QUORUM_APPROVER_IDENTITY_UNVERIFIED bind approvergovernance_registry head
Q5 approval is fresh / not drifted from the artifact none — no freshness/drift check approval can predate hash change APPROVAL_AFTER_ARTIFACT_HASH_DRIFT re-bind approval to artifact_hash_ref
Q6 approved object not superseded/revoked none in quorum no supersession check AUTHORIZATION_CHANGED_SAME_EFFECT_DUPLICATE (re-auth) lifecycle check at admission
Q7 proposer ≠ approver (self-exclusion) present (read) QUORUM_NOT_SATISFIED
Q8 apply-time re-proof present (fn_apr_block_unimplemented_handler) (blocks)
Q9 nonce issued by authority, single-use none no nonce surface NONCE_ISSUER_NOT_AUTHORITY nonce ledger bound to attempt

4. Controlling reading

  • QUORUM_SEMANTICS_READ — the obligation "read quorum body" is discharged, so G2_HOLD_QUORUM_SEMANTICS_UNPROVEN does not apply.
  • BUT quorum is necessary-not-sufficient: it proves vote tiers, not effect/artifact/identity binding (Q3–Q6, Q9). For register_dot, quorum_passed=true must be combined with the authority envelope ([[rs5a-07]]) before admission. Treating quorum_passed=true as sufficient is a fail-open the action contract forbids.
  • Net obligation status: QUORUM_PROVEN_BUT_BINDING_INSUFFICIENT ⇒ each unmet obligation is fail-closed.