KB-3F0F rev 2

23-P1 — IU Text-as-Code Edit / Proposal / Merge Model Design (rev2)

11 min read Revision 2
pack-23p1designtext-as-codeeditmergeproposalparent-childmulti-agentrev2

23-P1 — IU Text-as-Code Edit / Proposal / Merge Model — Design Note (rev2)

Date: 2026-05-06 Author: Opus (Claude) Status: DESIGN rev2 — chờ GPT/User review. Không implement. Tầm nhìn: Git-like workflow cho miếng thông tin. Multi-agent proposal/review/merge. Nguyên tắc: Thiết kế full model, implement phân kỳ. Phase 1 = dùng được ngay.


§0. Terminology Map (Git ↔ IU)

Git / Text-as-Code IU Equivalent Note
Repository information_unit 1 IU = 1 quản trị unit
Commit unit_version (merged) Immutable snapshot
HEAD version_anchor_ref Pointer to current merged version
Branch tip unit_version (proposed) Candidate chưa merge
Merge base base_version_ref Version gốc mà proposal dựa trên
Pull request Edit proposal (proposed UV) Candidate + review metadata
Merge fn_iu_merge_edit Accept proposal → update HEAD
Reject fn_iu_reject_edit Decline proposal
Revert New UV with body = old version body Phase 2+
Build artifact Rendered document Assemble children → full doc
CI gate Invariant verify + health check Before merge
CODEOWNERS owner_ref + edit_policy Phase 2+
.gitignore N/A Không applicable

§1. Text-as-Code Principles từ ngành IT

# Principle IT equivalent IU application Phase
1 Immutable version history Git commit log UV INSERT-only 1
2 Branch/proposal model Git branch / PR Proposed UV 1
3 Review/merge gate Code review Reviewer trước merge 1 (auto), 2 (manual)
4 Optimistic concurrency Many branches Nhiều proposed UV cùng base 2
5 Diff/patch git diff Compute diff base→proposed 2
6 Conflict detection Merge conflict Cùng base, khác nội dung 2
7 Revert git revert New UV = old body 2
8 CI/lint/test gates CI pipeline Invariant verify 1
9 Ownership/approval CODEOWNERS edit_policy per IU 2
10 Release/render Build artifact Assemble children 1 (basic)

§2. Current Incomex Primitives

Primitive Status Maps to
information_unit table ✅ Exists Repository
unit_version table ✅ Exists Commit history
fn_iu_create ✅ Live Init + first commit
fn_iu_create_plan ✅ Live Dry-run
Gateway guard ✅ Enforced Protected branch
canonical_address ✅ Immutable File path / URI
version_anchor_ref ✅ FK to UV HEAD pointer
parent_or_container_ref ✅ FK nullable Parent directory
content_hash ✅ On UV Content integrity
version_seq ✅ On UV Version numbering
identity_profile JSONB ✅ On IU Metadata

§3. Missing Primitives

# Missing Purpose Phase
1 UV lifecycle_status (proposed/merged/rejected/superseded) Proposal lifecycle 1
2 UV base_version_ref (FK parent UV) Conflict detection, diff base 1
3 Merge function Accept proposal → update HEAD 1
4 Sort order cho children Render document 1
5 Diff metadata Display changes 2
6 Conflict detection Multi-agent 2
7 Review status/actor Manual review 2
8 Revert function Undo 2
9 Edit policy per IU Auto-merge vs require review 2
10 Test/lint linkage Coverage map 3

§4. Parent/Child IU Model

Structure

IU-0 (parent, unit_kind=design_doc)
├── IU-0.§0 (child, sort_order=10)
├── IU-0.§1 (child, sort_order=20)
├── IU-0.§2 (child, sort_order=30)
└── IU-0.§3 (child, sort_order=40)

[rev2] Sort Order Storage Options

Option Pro Con Migration path
A. identity_profile JSONB Không DDL, nhanh Query phải cast JSONB, index phải expression index → core column nếu cần
B. Core column sort_order INT Query sạch, index native Cần ALTER TABLE Final destination
C. Edge metadata trên CONTAINS Normalize, sort là property của relation Query phức tạp hơn → nếu edge-centric design

Phase 1 recommendation: Option A (JSONB) — nhanh, không DDL mới. Ghi rõ: migration → Option B khi scale cần.

Quy tắc

  • Sửa child: INSERT new UV cho child. Parent KHÔNG tạo version mới.
  • Parent version chỉ thay đổi khi: thêm/xóa/reorder children, hoặc sửa metadata parent.
  • Render parent = dynamic assembly, không cache.
  • Orphan child (mất parent) → health incident, không auto-delete.
  • Nesting: recursive parent_or_container_ref cho phép con có cháu.

§5. Multi-Agent Concurrent Workflow

Scenario (Phase 2+)

        base version (v3, merged)
       /         |           \
Agent A propose  Agent B propose  Agent C propose
       \         |           /
     Reviewer compare diffs
              |
     Accept A → merge (new merged version)
     Reject B, Supersede C

[rev2] Version Sequence Semantics — 2 options

Option X: Proposals consume version_seq Option Y: Proposals get seq on merge only
Mechanism Mỗi proposed UV nhận version_seq khi INSERT Proposed UV có version_seq=NULL (hoặc 0). Merge assigns next seq
Merged history Gaps: v1(merged), v2(merged), v3(proposed→merged), v4(rejected), v5(superseded) Clean: v1, v2, v3 = chỉ merged versions
Pro Đơn giản, 1 sequence Clean numbering, "version 5" = lần merge thứ 5
Con version_seq không đại diện merge history rõ ràng Cần kiểm constraint NOT NULL / UNIQUE trên version_seq
Constraint risk Low — unique(unit_id, version_seq) vẫn work PHẢI inspect — nếu NOT NULL constraint → cần ALTER hoặc workaround

Opus preference: Option Y (seq on merge only) — cleaner semantics. Nhưng PHẢI runtime inspection xác nhận version_seq constraints trước khi chọn.

⚠️ [rev2] Warning: UV = Proposal Object needs runtime verification

Dùng unit_version làm proposal container là gọn, nhưng phải xác nhận:

  • version_seq constraint cho phép NULL hoặc nhiều proposed UV cùng unit?
  • fn_iu_verify_invariants có assume exactly 1 current UV không?
  • version_anchor_ref logic có bị break với nhiều proposed UV?
  • Birth trigger behavior với UV lifecycle_status ≠ merged?

23-P2 read-only inspection PHẢI trả lời các câu hỏi này trước implementation.


§6. Function Set

Core (Phase 1):

fn_iu_propose_edit(address, new_body, actor)
  → INSERT UV status=proposed, base_version_ref=current HEAD
  → Return proposal_uv_id

fn_iu_merge_edit(proposal_uv_id, reviewer)
  → Verify: UV exists, status=proposed, invariants OK
  → UPDATE UV status=merged, assign version_seq
  → UPDATE IU version_anchor_ref + content_anchor_ref
  → Return merged result

fn_iu_edit(address, new_body, actor)
  → Wrapper: propose + auto-merge in 1 transaction
  → [rev2] Policy check: auto-merge allowed for this IU?

Phase 2+:

fn_iu_reject_edit(proposal_uv_id, reviewer, reason)
fn_iu_edit_plan(address, new_body, actor)  — dry-run
fn_iu_revert(address, target_version_seq, actor)

[rev2] fn_iu_edit Policy Hook

fn_iu_edit wrapper KHÔNG auto-merge nếu policy nói không:

-- Pseudocode inside fn_iu_edit:
v_policy := read_edit_policy(IU);
IF v_policy = 'require_review' THEN
  -- Only propose, don't merge
  RETURN fn_iu_propose_edit(...) || '{"auto_merged": false, "requires_review": true}';
ELSE
  -- Propose + merge
  RETURN fn_iu_propose_edit(...) + fn_iu_merge_edit(...);
END IF;

Policy source: identity_profile->>'edit_policy' hoặc dot_config per unit_kind. Phase 1 default = auto_merge (single Agent). Phase 2: enacted/protected IUs → require_review.


§7. [rev2] Gateway Marker Strategy — Explicit Allow-list

Không dùng prefix fn_iu_%. Quá rộng — helper functions không intended write có thể pass guard.

Allow-list explicit:

-- dot_config key:
iu_create.gateway.allowed_marker_values = fn_iu_create,fn_iu_propose_edit,fn_iu_merge_edit,fn_iu_edit

Guard function đọc allow-list:

v_allowed := string_to_array(
  (SELECT value FROM dot_config WHERE key='iu_create.gateway.allowed_marker_values'),
  ','
);
IF v_current = ANY(v_allowed) THEN RETURN NEW; END IF;

Thêm marker mới = thêm vào dot_config, không patch guard function.

⚠️ Guard function hiện check exact single value. Cần patch sang allow-list. Đây là scope 23-P3 (guard patch), sau 23-P2 inspection.


§8. Schema Evidence Needed (23-P2 Inspection)

# Question Why
1 unit_version columns/constraints version_seq NULL? UNIQUE?
2 lifecycle_status trên UV exists? Nếu có → reuse. Nếu không → ALTER
3 base_version_ref exists? Likely no → cần ALTER
4 fn_iu_verify_invariants behavior với nhiều UV Assume 1 current?
5 Birth trigger behavior với proposed UV Block? Warn? Ignore?
6 Guard function exact check logic Single value vs allow-list
7 sort_order anywhere on IU identity_profile? core column?
8 Edge table support cho CONTAINS + order metadata Can store sort_order?

§9. Minimum Production Workflow v1

1. Create parent IU    → fn_iu_create(doc_address, title, metadata, actor)
2. Create child IUs    → fn_iu_create(section_address, title, body, actor, parent_ref=parent.id)
3. Edit child          → fn_iu_edit(section_address, new_body, actor)
                         [internally: propose + policy check + auto-merge]
4. Read/render         → SELECT children WHERE parent=? ORDER BY sort_order → assemble
5. History             → SELECT * FROM unit_version WHERE unit_id=? ORDER BY version_seq

§10. What NOT to Do Yet

  • Full 3-way merge, vector outbox, Directus UI, role separation, detector, release builder, semantic lint, concurrent conflict auto-resolve, package system

§11. Implementation Phases

Phase 1: Miếng thông tin dùng được

# Deliverable Prereq
1 23-P2 read-only inspection (UV constraints, guard logic, etc.) This design approved
2 Schema patch: UV add lifecycle_status + base_version_ref (if needed) 23-P2 results
3 fn_iu_propose_edit + fn_iu_merge_edit Schema ready
4 fn_iu_edit wrapper (with policy hook, default auto_merge) Core functions ready
5 Guard patch: allow-list marker values Before new functions dispatch
6 Parent/child: sort_order in identity_profile Low effort
7 Convert 2 pilot docs → real IUs (parent + children) Functions ready
8 Smoke test full cycle: create → edit → read → render Data ready

Phase 2: Multi-Agent Review

Phase 3: Advanced Text-as-Code

(Unchanged from rev1)


23-P1 Design rev2 | 2026-05-06 | 8 GPT patches applied | Chờ review