05 — Axis Proposal Layer: GitLawb vs Git-server vs native-PG vs Hybrid (recommend Hybrid PG-native, design-only, 2026-06-02)
05 — Axis Proposal Layer: GitLawb-style vs Git-server vs native-PG vs Hybrid (Branch E)
Branch E. Evaluate proposal-as-code / Git-like approaches for uncertain topic/axis proposals, without hype. Principle (mission): PG is truth/runtime. The proposal layer is draft/review/versioning for uncertain changes. Verdict: HYBRID, PG-NATIVE. Implement the Git-like model (base-version, diff, review gates, merge, rollback) inside PG using substrate that already exists (
unit_edit_draft,approval_requests,iu_merge_set/iu_split_set,doc_reviews,axis_assignmentzones). Do not stand up an external Git/GitLab/Gitea/GitLawb system now.
05.0 What "proposal layer" must do here
For uncertain axis/topic changes (a proposed topic node, a re-parenting, a merge, an IU-topic assignment with low confidence), the system needs: a draft that does not touch truth; a diff against the current truth; a review (human/AI gates); a merge/apply into PG truth on approval; rollback; identity/signing/audit; and agent participation. Crucially, PG must remain the runtime source of truth — the proposal layer is scaffolding around it, not a parallel truth.
05.1 What already exists in PG (the "we mostly have it" finding)
| Git concept | Live PG substrate | Evidence |
|---|---|---|
| branch / working copy | unit_edit_draft (base_version_ref, draft_body, draft_status) |
optimistic working copy off a base version |
| base / merge-base | unit_edit_draft.base_version_ref + base_content_hash |
3-way-merge basis |
| diff | base_content_hash vs draft_content_hash; current_state vs proposed_action in approval_requests |
content + structured diff |
| conflict detection | unit_edit_draft.stale_at (base moved) |
optimistic concurrency |
| review (PR) | doc_reviews (review_gate_1, review_gate_2, resolution); approval_requests+apr_approvals |
two-gate + quorum |
| merge / apply | unit_edit_draft.applied_version_ref; iu_merge_set/iu_split_set (change_set_id, idempotency_key) |
apply with change-set + idempotency |
| commit history | unit_version, registry_changelog, iu_tree_change_log |
versioned history |
| revert | iu_merge_set.rolled_back_at/by/reason; approval_requests revert |
rollback primitive |
| signed-off-by | apr_approvals(approver, approver_type, decision); L0–L4 (doc 02) |
identity + authority |
Finding: the Git-like model is ~80% present in PG already. What is missing is a unified proposal envelope over axes/topics — and axis_assignment.zone (doc 04) supplies the Candidate/Quarantine working states.
05.2 The four options, compared across the mission's dimensions
| Dimension | GitLawb-style (purpose-built "law/governance-as-git", in-house) | GitLab/Gitea-style (external git server) | Native PG proposal tables | Hybrid PG-native (recommended) |
|---|---|---|---|---|
| Fit for uncertain topic/axis proposals | High (diff/branch model) but axes are rows, not files — impedance mismatch | Low — files/repos, not governed rows | High — proposals are rows with confidence/zone | High — PG rows + Git-like draft/diff/merge semantics |
| Fit for agent workflows | Medium (agents commit text) | Low (agents push git — heavy, side-channel) | High (agents write approval_requests/axis_assignment) |
High (agents propose into PG; same as runtime) |
| Identity / signing / audit | Custom; risk of split-brain with PG identities | git identities ≠ governance identities (split-brain) | Native (apr_approvals, L0–L4) |
Native (one identity model, doc 02) |
| Diff / review / merge | Strong (git's strength) | Strong | Adequate (*_content_hash, gates, change-sets) |
Strong-enough (reuse unit_edit_draft 3-way + doc_reviews gates) |
| Sync-to-PG | Fragile — git→PG sync is a second pipeline that can drift | Fragile — extra connector, eventual consistency | N/A (already in PG) | N/A (proposal lives in PG; apply is a transaction) |
| Rollback | git revert ≠ PG state revert | same | PG transaction + change-set revert | PG transaction + change_set_id + rollback runbook |
| Operational complexity | High (build+run a versioning engine) | High (run+secure a git server, webhooks, auth) | Low | Low-medium (one proposal envelope over existing tables) |
| Maturity / risk | Unproven in-house | Mature product, but wrong substrate for governed rows; new attack surface | Proven here (211 approval_requests, live) |
Proven — reuses live, governed substrate |
05.3 Why not external Git (now)
- Substrate mismatch: axes/topics are governed rows with FK, coverage, owners, bitemporal validity — not files. Forcing them into a git repo creates a translation layer.
- Identity/sign split-brain: git commit identities are not the governance identities (
approver_type, council membership, sovereign). The L0–L4 model (doc 02) and Điều 39's "no rule = no auto = default human" cannot be enforced by git. - Sync-to-PG fragility: a git→PG sync is a second source of truth that can drift — violating "PG is the source of truth" and adding a five-layer-sync burden.
- New attack surface & ops cost: a git server is infra to secure, back up, and authorize — for no benefit over PG transactions.
GitLab/Gitea/GitLawb remain a possible future for human-facing collaborative document editing at scale (e.g. editing law text bodies), where git's text-merge UX genuinely helps. That is a content-editing concern (could front unit_edit_draft), not the axis/topic governance-proposal concern. Defer; do not build now.
05.4 The recommended hybrid: one PG-native proposal envelope
A proposal is an approval_requests row (the governed envelope) that may carry one or more working artifacts:
- content edit →
unit_edit_draft(base-version + draft body + hash); - uncertain membership →
axis_assignmentrows inzone='candidate'/'quarantine'; - node create/merge/split/re-parent → proposed
taxonomy/iu_relationchanges captured inproposed_action jsonb+ aniu_merge_set/iu_split_set-style change record (withchange_set_id,idempotency_key, rollback).
Lifecycle: DRAFT (working artifact, no truth touched) → DIFF (hash/structured) → REVIEW (doc_reviews gates + apr_approvals quorum, at the L0–L4 level set by risk) → APPLY (one transaction, L3 build-auth if it COMMITs born substrate) → VERIFY (recompute projections; reconstruction fingerprint if structural) → CLOSE (history in unit_version/registry_changelog; candidate zones promoted to approved). Rollback at any pre-apply step is free (drop the draft); post-apply uses change_set_id + the rollback runbook.
Agent rights (doc 08): agents may create drafts, write candidate/quarantine assignments, and propose; agents may not set zone='approved', set a build-auth active, or apply high-risk merges/splits (those need human/council per doc 02 and Điều 39 Golden Rule "AI proposes, never self-enacts").
05.5 Verdict
HYBRID, PG-NATIVE — recommended and largely already built. Reuse unit_edit_draft (Git-like drafts), approval_requests/apr_approvals/doc_reviews (review/merge governance), iu_merge_set/iu_split_set (change-set + idempotency + rollback), and axis_assignment.zone (Candidate/Quarantine). No external Git system now; revisit a git-fronted content editor only if human collaborative text-editing demands it. This keeps one source of truth, one identity model, and one rollback story.