10 — Approval Lifecycle Model (Đ32)
10 — Approval Lifecycle Model (Branch J)
A lifecycle for grouping/classification/pin/phantom/pivot-coverage policies, built entirely on the existing Đ32 spine (approval_requests status machine + apr_approvals + nrm_approval_rules). No new approval mechanism.
Mapping the requested lifecycle onto live Đ32 states
Live approval_requests.status CHECK = pending → approved → applied / rejected / expired. The richer requested lifecycle maps as:
| Requested state | Live representation | Substrate |
|---|---|---|
| detected | issue row | system_issues (auto, no approval) |
| proposed | approval_requests.status='pending' (created by dot-apr-propose) |
Đ32 |
| under_review | pending with partial apr_approvals rows |
Đ32 |
| approved | status='approved' (quorum met, not yet applied) |
Đ32 §4.2 |
| active | status='applied' + object status='active' |
Đ32 + object |
| suspended | object status flip (is_active=false) via update_item APR |
Đ32 |
| retired | approval_requests(retire) applied + object status='retired'/superseded_by |
Đ32 |
| superseded | object superseded_by set via new approved APR |
Đ32 |
Per-transition governance table
| Transition | Actor | DOT allowed | Approval requirement | Approval path | Audit record | Rollback | system_issue update | event update | UI visibility |
|---|---|---|---|---|---|---|---|---|---|
| detected → proposed | A-tier scan DOT (GOV-SIV) | scan (read-only) | none to detect; propose creates APR | dot-apr-propose → approval_requests |
issue.detected_at | n/a | issue opened | system.issue_opened |
flagged on RP surface |
| proposed → under_review | reviewers (president/ai_council) | none | — | apr_approvals rows accrue |
apr rows | n/a | — | — | shows "pending approval" badge |
| under_review → approved | quorum trigger | none | Đ32 §4.2: high=president+≥2 ai_council+0 reject; med=≥1 president; low=≥1/auto | apr_approvals UNIQUE(apr_id,approver); no-self-approve §4.3.1 |
apr decision | n/a | — | mother.proposal.approved (activate) |
"approved" badge |
| approved → active(applied) | B-tier apply DOT (GOV-DOT) | apply (mutating, paired) | already approved | dot-apr-execute:* handler |
governance_audit_log + registry_changelog |
backup .bak-{session} (Đ35 §6.2) |
— | object-specific event | object appears live |
| active → suspended | B-tier DOT | update_item |
≥1 approve (low) | Đ32 | changelog | re-activate | — | governance.blocked (if mother lane) |
hidden/greyed |
| active → retired | B-tier DOT | retire |
parity gate (Đ30) + Đ32 | Đ32 + Đ30 regression | changelog | snapshot revert | issue resolved | piece.retired/object retire |
removed (redirect) |
| any → rejected | reviewer | none | — | apr_approvals decision=reject |
apr row | n/a | issue stays open | mother.proposal.rejected |
"rejected" note |
| pending → expired | system_auto_expire cron |
none | TTL | status=expired | — | n/a | — | — | dropped |
Risk → authority routing (live apr_action_types.risk_level + nrm_approval_rules)
- low (e.g.
create_itema label/pivot row): ≥1 approve or valid auto-approve. - medium (e.g.
add_field/schema_adda new policy column/table): ≥1president. - high (e.g.
patch_ops_code;amend_law/enact_nrmfor threshold/phantom law clauses): ≥1president+ ≥2ai_council+ 0 reject; doc_level 1-2 →council_review.
No-self-approval (verbatim Đ32 §4.3.1)
"Cấm self-approve cho high-risk request của chính người/agent tạo request." + §4.3.2 "Có reject mở thì không được approve đè; phải mở chu kỳ review mới." A valid approval = an apr_approvals row by a distinct approver; machine auto-apply-function/orchestrator-s142b are NOT sovereign approvals (they do not write apr_approvals).
What a valid approval artifact is (for Registries-Pivot commits)
- An
approval_requestsrow with the correctrequest_type_code(reclassify/rule_change/schema_add/new_dot/retire) andtarget_collection. - Sufficient
apr_approvalsrows meeting the §4.2 quorum for the action'srisk_level. status='approved'→applied; applied via a DOT handler, not hand-SQL.- (For law clauses — threshold/phantom)
council_reviewon the normative_registry doc +governance_audit_logminute.
Live gap: none of these exist for any Registries-Pivot grouping artifact (os_proposal_approvals=0; only S178 DOT-repair approvals exist). ⇒ COMMIT_FORBIDDEN until the lifecycle above is actually walked.
Reuse statement
Every state, actor, and gate above already exists in Đ32/Đ35/Đ45. The dormant mother.proposal.*/governance.blocked|unblocked event types (active=false) are the ready-made activation/lifecycle events — enabling them (approval-gated) is the only "new" step, and it is additive.