P5 — Schema Draft v0.2: Text as Code — Unit / Publication / Metadata
P5 — Schema Draft v0.2: Text as Code — Unit / Publication / Metadata
Loại: Schema design note — Điều 38 Text as Code Phase: P5 (Schema Phase), đầu vào từ C1 + C2 + C1A + LSL-01 Trạng thái: DRAFT v0.2 — Patched theo GPT Round 1 (12 điểm) + Round 2 (7 điểm). Chờ User duyệt final. Ngày soạn: 2026-04-26 | Phiên: S181 Agent soạn: Opus 4.6 (Desktop) GPT review: Round 1 — PASS có điều kiện (12 patches). Round 2 — PASS có điều kiện nhẹ (7 patches). Inputs: LSL-01 v0.3 + v0.4, C1A (OFFICIAL), C1, C2, HOW-TO-READ, Mainline Cross-check, Đ24 label system, Đ33 PG Law
1. Mục tiêu
Chuyển design notes tiền-schema (C1 + C2 + C1A) thành draft schema cụ thể — đủ chi tiết để GPT review tính nhất quán, đủ rõ để chuyển thành DDL thật sau khi P5 PASS và User duyệt implementation/migration path.
P5 v0.2 trả lời: "Băng chuyền chính gồm bao nhiêu bảng, bảng nào chứa gì, quan hệ thế nào, lifecycle chạy ra sao?"
P5 v0.2 là bản vẽ kỹ thuật — pseudo-DDL để diễn đạt ý, KHÔNG apply vào production. DDL thật chỉ được thực hiện sau khi P5 PASS và User duyệt implementation/migration path riêng.
2. Phạm vi / Không làm
2.1 Trong phạm vi
logical_unit— danh tính miếng thông tinunit_version— nội dung miếng tại 1 thời điểmpublication— bản công bố (document/luật/SOP/knowledge)publication_member— membership: publication trỏ tới unit_versions- Label mapping tương thích Đ24 (
entity_labels) section_type_vocab— controlled vocabulary cho section_type- Length flags / exception metadata trên unit_version
- Vector projection hooks (sync status + chunk manifest concept)
- Review / change-set / APR integration hooks
- Birth gate readiness hooks
2.2 Không làm
- Không full Component/BOM schema (thuộc C3/P5b)
- Không migration thật / apply SQL vào production
- Không production write path / transaction code
- Không DOT implementation / cron jobs (thuộc P6 — checker/DOT design)
- Không Qdrant implementation / embedding pipeline
- Không sửa C1/C2/C1A/LSL/L1–L5
- Không UI / workflow engine / rendering engine
3. Nguyên tắc thiết kế
DP-1: 2 bảng tách biệt cho logical unit và unit version
Quyết định: Giải quyết C1-OD12 + C2-OD-M1.
Chọn 2 bảng (logical_unit + unit_version) thay vì 1 bảng gộp.
Rationale:
- LSL-01 §4 phân biệt rõ: logical unit = danh tính (sống xuyên versions), unit version = nội dung (tại 1 thời điểm).
- Identity metadata (canonical_address, parent, sort_order, section_type, owner) ổn định xuyên versions → gắn logical_unit.
- Content metadata (title, body, description, review_state) thay đổi per version → gắn unit_version.
- Gộp 1 bảng buộc duplicate identity metadata mỗi version, vi phạm NT11 (Khai tối thiểu).
Tradeoff: 2 bảng = thêm 1 JOIN khi query. Nhưng JOIN trên PK/FK indexed là O(1), chấp nhận được. Lợi ích: address truly bất biến, parent thay đổi 1 chỗ, version history sạch.
DP-2: Publication là bảng riêng, membership là bảng junction
Quyết định: Giải quyết C1A-OD-C1A-08.
publication= bảng chứa governance metadata (doc_code, version, lifecycle, owner, authority).publication_member= bảng junction(publication_id, logical_unit_id, unit_version_id, render_order).- Bảng
publication_memberdùng cho MỌI lifecycle stage (proposed lẫn enacted). Khi publication enacted → membership bị lock (immutable). Khi proposed → membership có thể thay đổi. - Membership tách biệt hoàn toàn với Đ24
entity_labelsclassification labeldoc=X.
Rationale: CI-4 (label ≠ membership). Label "miếng này nói về Đ38" ≠ "miếng này là phần chính thức của PUB-Đ38-v3.0-ENACTED". Junction table rõ ràng, có constraint UNIQUE per (publication_id, logical_unit_id), hỗ trợ render_order per publication.
DP-3: Classification labels dùng Đ24 entity_labels
Quyết định: Giải quyết C1A-OD-C1A-04.
Logical unit có code (canonical_address hoặc entity code) → map vào entity_labels.entity_code. KHÔNG tạo label table riêng. Nếu scale issue phát sinh, giải quyết bằng indexing/partitioning trên entity_labels, KHÔNG phá Đ24 SSOT.
DP-4: section_type là FK controlled vocabulary, thuộc logical_unit
Quyết định: Giải quyết C2-OD-M8.
section_type gắn logical_unit (mô tả vai trò cấu trúc, ổn định xuyên versions). Thay đổi section_type = structural change, qua change-set. section_type KHÔNG phải Đ24 classification label (IN-3 HOW-TO-READ), nhưng có thể map sang Đ24 làm facet nếu cần — quyết định map thuộc P6.
Lưu ý: section_type_vocab và publication_type_vocab là controlled vocabulary cho structural/governance metadata, không thay thế Đ24 taxonomy_facets / entity_labels. Nếu cần pivot cross-system (ví dụ: query tất cả entity loại article xuyên hệ thống), thì map/sync sang Đ24 bằng rule riêng — không đặt classification data vào vocab tables.
DP-5: Profile metadata phân tầng theo object family
Quyết định: Giải quyết C2-OD-M2.
Chọn JSONB cho profile metadata, nhưng phân tầng rõ:
| Object | Profile field | Mô tả |
|---|---|---|
logical_unit |
identity_profile JSONB |
Profile cho identity metadata mở rộng per section_type (ví dụ: legal_effect, is_normative, canonical_doc_label). Ổn định xuyên versions. |
unit_version |
content_profile JSONB |
Profile cho content metadata mở rộng per section_type/doc_family (ví dụ: enforcement_date, actor, frequency). Thay đổi per version. |
publication |
publication_profile JSONB |
Profile cho publication metadata mở rộng per publication_type (ví dụ: review_deadline, distribution_list, kb_path). |
Profile trên component, relation, change-set = deferred cho C3/P5b/P6.
Rationale: C2/L3 nói metadata áp cho nhiều object families. JSONB linh hoạt, thêm field không cần ALTER TABLE. JSON Schema validation (application-level hoặc PG check constraint) đảm bảo required fields.
Tradeoff: JSONB mất type safety ở DB level. Bù bằng: birth gate validation + DOT daily check + JSON Schema.
DP-6: Publication member là membership table, không materialized view
Quyết định: Giải quyết C2-OD-M6.
Dùng publication_member table cho mọi lifecycle stage. Enacted publication → membership locked (trigger/app block INSERT/UPDATE/DELETE). Table với lock mechanism = kiểm soát tốt hơn materialized view.
DP-7: Canonical address sinh tại birth, unique constraint
Quyết định: Giải quyết C1A-OD-C1A-05.
- Format:
{DOC_CODE}-S{section}-P{paragraph}[-{sub}](giữ tương thích hiện tại). - UNIQUE constraint trên
logical_unit.canonical_address. - Sinh bởi: Agent manual hoặc system-auto (birth path).
- Nếu system-auto: reservation mechanism qua
SELECT FOR UPDATEhoặc sequence, tránh race condition. - Bất biến sau birth — trigger hoặc application-level enforcement.
4. Entity map
┌──────────────┐ 1:N ┌──────────────┐
│ logical_unit │─────────────▶│ unit_version │
│ │ │ │
│ identity │ │ content │
│ address │ │ body │
│ parent_id ◄──┼── self-ref │ lifecycle │
│ section_type │ │ content_prof │
│ identity_prof│ │ content_hash │
│ doc_code ────┼── structural └──────────────┘
│ (NOT FK) │ lineage │
└──────┬───────┘ binding N:M via
│ publication_member
│ N:M via │
│ entity_labels (Đ24) ▼
│ ┌──────────────┐
▼ │ publication │
┌──────────────┐ │ │
│ entity_labels│ │ doc_code │
│ (Đ24 exist.) │ │ version │
│ │ │ lifecycle │
│ entity_code │ │ authority │
│ facet_code │ │ pub_profile │
│ label_value │ └──────────────┘
└──────────────┘
Controlled vocabularies (structural/governance, NOT Đ24 replacement):
┌──────────────────────┐ ┌──────────────────────┐
│ section_type_vocab │ │ publication_type_vocab│
│ (FK from logical_unit)│ │ (FK from publication) │
└──────────────────────┘ └──────────────────────┘
Change-set & review (hooks):
┌──────────────┐ 1:N ┌──────────────────────┐
│ change_set │────────────▶│ change_set_member │
│ │ │ (logical_unit_id, │
│ lifecycle │ │ old_version_id, │
│ apr_ref │ │ new_version_id) │
│ snapshot_ref │ └──────────────────────┘
└──────────────┘
Vector projection (hooks + manifest concept):
unit_version.vector_sync_status
unit_version.vector_synced_at
unit_version.vector_chunk_count (derived/cache)
→ Chunk manifest table/structure thuộc P6 design,
P5 cung cấp hook đủ kiểm CI-2.
5. Draft table/collection model
CẢNH BÁO: Pseudo-DDL dưới đây là design notation — KHÔNG apply vào production. Tên bảng/cột/kiểu dữ liệu là ĐỀ XUẤT, chưa phải chốt.
5.1 logical_unit
-- PSEUDO-DDL — KHÔNG APPLY
CREATE TABLE logical_unit (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
canonical_address TEXT NOT NULL UNIQUE,
-- Bất biến sau birth. Format: {DOC_CODE}-S{n}-P{n}[-{sub}]
-- Identity field, KHÔNG phải label (LSL-01 §6.2, §8.4)
-- Structural / document-lineage binding
doc_code TEXT NOT NULL,
-- doc_code là STRUCTURAL / DOCUMENT-LINEAGE BINDING
-- của logical_unit — xác định miếng này thuộc dòng
-- tài liệu nào (D38, HP, SOP-DEPLOY...).
-- KHÔNG PHẢI classification label Đ24.
-- Classification doc=X nếu cần phải nằm ở
-- Đ24 entity_labels.
--
-- FK NOTE: KHÔNG FK trực tiếp vào publication.doc_code
-- vì publication.doc_code không unique (nhiều versions).
-- Validate sự tồn tại bằng application/trigger
-- kiểm doc_code tồn tại trong publication lineage
-- registry / document_series / publication.doc_code set.
-- Chi tiết registry: deferred theo OD-P5-04.
parent_id UUID REFERENCES logical_unit(id),
-- Self-ref. NULL = root unit. Cùng doc_code (I5).
-- Structural relation, integrity rule (C1 §4.5).
sort_order INTEGER NOT NULL DEFAULT 0,
-- Thứ tự canonical trong cây.
-- Khác render_order (thuộc publication).
-- Identity metadata
section_type TEXT NOT NULL REFERENCES section_type_vocab(code),
-- Unit metadata, KHÔNG phải Đ24 classification label (IN-3).
-- Mặc định logical unit-level (DP-4, C2 OD-M8).
section_code TEXT,
-- Human-readable alias (§1, §2.1, §A3...).
-- Có thể đổi. KHÔNG phải identity.
owner TEXT NOT NULL,
-- Mặc định kế thừa từ publication owner.
-- Identity profile (DP-5 phân tầng)
identity_profile JSONB DEFAULT '{}',
-- Profile mở rộng per section_type cho identity-level.
-- Ví dụ: {"is_normative": true, "canonical_doc_label": "Đ38"}
-- Ổn định xuyên versions. JSON Schema validation ở app level.
-- System auto
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- Derived / cache
tier TEXT,
-- DERIVED / CACHE: DOT/checker tính từ vị trí
-- trong cây cấu trúc (M7, NT11).
-- Agent KHÔNG khai tay. DOT derive + checker verify.
lifecycle_status TEXT NOT NULL DEFAULT 'draft_only'
CHECK (lifecycle_status IN (
'active', -- Có ≥1 version enacted
'draft_only', -- Chỉ có draft versions, chưa bao giờ enacted
'retired' -- Quyết định retire qua change-set + APR.
-- Khi retired: version enacted cuối → retired,
-- miếng hết hiệu lực.
)),
-- Explicit column (không derived) vì:
-- 1) Tránh query N versions mỗi lần check status.
-- 2) DOT verify consistency với versions.
-- Transition: active→retired chỉ qua change-set+APR.
-- Constraints
-- parent_same_doc: parent phải cùng doc_code (I5).
-- Enforce via trigger/birth gate (PG check constraint
-- không thể self-join).
);
-- Indexes
CREATE INDEX idx_lu_doc_code ON logical_unit(doc_code);
CREATE INDEX idx_lu_parent ON logical_unit(parent_id);
CREATE INDEX idx_lu_section_type ON logical_unit(section_type);
5.2 unit_version
-- PSEUDO-DDL — KHÔNG APPLY
CREATE TABLE unit_version (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
logical_unit_id UUID NOT NULL REFERENCES logical_unit(id),
-- Content metadata
version_number INTEGER NOT NULL DEFAULT 1,
-- Sequential per logical_unit.
title TEXT NOT NULL,
body TEXT,
-- Content payload. NULL cho heading/container units
-- (OD-C1A-09: structural node không có content).
description TEXT,
-- Mặc định required cho content-bearing unit.
-- Exception theo section_type/profile rule:
-- heading/container MAY have NULL description.
-- Birth gate enforce per section_type config.
-- Content integrity
content_hash TEXT,
-- DERIVED: hash bao gồm body + title + description
-- + content_profile. System auto compute.
-- Phục vụ: change detection, review verification,
-- vector re-embed trigger.
-- Lifecycle (per C1 §5.1)
lifecycle_status TEXT NOT NULL DEFAULT 'draft'
CHECK (lifecycle_status IN (
'draft', -- Mới tạo, chưa approve. Sửa tại chỗ.
'enacted', -- Approve qua change-set + APR. BẤT BIẾN.
'superseded', -- Bị thay bởi version mới enacted. Giữ audit.
'retired' -- Cascaded từ quyết định retire logical_unit.
-- Khi logical_unit retired → version enacted
-- cuối cùng chuyển retired (C1 §6.4).
-- INVARIANT: unit_version.retired CHỈ hợp lệ
-- khi logical_unit.lifecycle_status = 'retired'.
-- Xem INV-RETIRE §15.
)),
-- OD-P5-11: Council có thể mở rộng enum (withdrawn,
-- archived) nếu cần. Hiện giữ đúng C1 §5.1.
-- Review
review_state TEXT DEFAULT 'unreviewed'
CHECK (review_state IN (
'unreviewed', 'in_review', 'review_passed',
'review_failed', 'needs_re_review'
)),
-- Length management (C1A §8)
length_flag TEXT DEFAULT 'normal'
CHECK (length_flag IN ('normal', 'soft_limit', 'hard_limit')),
-- Derived: DOT hoặc trigger tính từ word count.
length_exception_reason TEXT,
-- Nếu hard_limit mà được approved giữ nguyên → ghi lý do.
-- NULL = chưa cần exception hoặc chưa quyết.
-- Content profile (DP-5 phân tầng)
content_profile JSONB DEFAULT '{}',
-- Profile mở rộng per section_type/doc_family cho content-level.
-- Ví dụ: {"enforcement_date": "2026-05-01", "actor": "ops-team"}
-- Thay đổi per version. JSON Schema validation ở app level.
-- Provenance
editor TEXT,
-- Ai sửa version này (khác owner logical unit).
provenance TEXT DEFAULT 'PROV-AI',
-- Phải map/tương thích Đ24 FAC-PROV hoặc controlled
-- vocabulary provenance hiện hành.
-- Values hợp lệ: PROV-AI / PROV-HUMAN / PROV-DOT /
-- các giá trị khác theo Đ24 FAC-PROV registry.
-- Agent KHÔNG tự sáng tác provenance value ngoài
-- vocabulary đã đăng ký.
-- Vector projection hooks
vector_sync_status TEXT DEFAULT 'pending'
CHECK (vector_sync_status IN ('pending', 'synced', 'stale', 'error')),
vector_synced_at TIMESTAMPTZ,
vector_chunk_count INTEGER DEFAULT 0,
-- DERIVED / CACHE: số canonical chunks hiện tại trong Qdrant
-- cho version này. DOT/sync worker cập nhật.
-- Phục vụ: kiểm CI-2 (canonical chunk ≤ 1 unit_version),
-- monitoring, và trigger re-sync.
-- Chi tiết chunk manifest (chunk_id, span_start, span_end,
-- embedding_model...) thuộc P6 design — xem §10.5.
-- System auto
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
enacted_at TIMESTAMPTZ,
-- System set khi lifecycle_status → enacted.
-- Constraints
UNIQUE (logical_unit_id, version_number),
-- Mỗi logical unit không trùng version number.
-- Business rules (enforce via trigger/app):
-- 1. Tối đa 1 version enacted per logical_unit tại bất kỳ thời điểm.
-- 2. Enacted version bất biến (C1 I2): block UPDATE trên
-- body/title/description/content_profile khi enacted.
-- 3. INV-RETIRE: retired CHỈ khi logical_unit.lifecycle_status = 'retired'.
);
-- Indexes
CREATE INDEX idx_uv_logical_unit ON unit_version(logical_unit_id);
CREATE INDEX idx_uv_lifecycle ON unit_version(lifecycle_status);
CREATE INDEX idx_uv_vector_sync ON unit_version(vector_sync_status)
WHERE vector_sync_status != 'synced';
5.3 publication
-- PSEUDO-DDL — KHÔNG APPLY
CREATE TABLE publication (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
doc_code TEXT NOT NULL,
-- Ví dụ: D38, HP, SOP-DEPLOY. Trùng across versions.
-- Structural identifier, KHÔNG phải Đ24 label.
version TEXT NOT NULL,
-- Ví dụ: '3.0', '4.6.3'.
-- Governance metadata
publication_type TEXT NOT NULL REFERENCES publication_type_vocab(code),
-- law, policy, sop, constitution, knowledge, design_note,
-- report, memo, draft, working.
-- Quyết định default risk tier (C1A §11.3).
name TEXT NOT NULL,
owner TEXT NOT NULL,
description TEXT,
-- Lifecycle
lifecycle_status TEXT NOT NULL DEFAULT 'proposed'
CHECK (lifecycle_status IN (
'proposed', 'enacted', 'superseded', 'retired'
)),
-- §9.7 C1A: PROPOSED → ENACTED → SUPERSEDED → RETIRED.
-- Authority
enacted_at TIMESTAMPTZ,
council_score NUMERIC,
approved_by TEXT,
-- Risk tier (C1A §11.3, LSL-01 §10.2)
risk_tier TEXT NOT NULL DEFAULT 'medium'
CHECK (risk_tier IN ('low', 'medium', 'high', 'highest')),
-- Publication profile (DP-5 phân tầng)
publication_profile JSONB DEFAULT '{}',
-- Profile mở rộng per publication_type.
-- Ví dụ: {"review_deadline": "2026-05-01",
-- "kb_path": "knowledge/dev/laws/dieu38.md",
-- "distribution_list": ["council", "ops"]}
-- System auto
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- Constraints
UNIQUE (doc_code, version)
);
-- Indexes
CREATE INDEX idx_pub_doc_code ON publication(doc_code);
CREATE INDEX idx_pub_lifecycle ON publication(lifecycle_status);
5.4 publication_member
-- PSEUDO-DDL — KHÔNG APPLY
-- Tên: publication_member (KHÔNG "published_snapshot_member")
-- Dùng cho MỌI lifecycle stage:
-- - proposed: membership có thể thay đổi, MAY reference draft versions
-- - enacted: membership LOCKED (immutable), CHỈ enacted versions (CI-5)
CREATE TABLE publication_member (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
publication_id UUID NOT NULL REFERENCES publication(id),
logical_unit_id UUID NOT NULL REFERENCES logical_unit(id),
unit_version_id UUID NOT NULL REFERENCES unit_version(id),
-- Render order (C1A §9.6)
render_order INTEGER NOT NULL DEFAULT 0,
-- System auto
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- Constraints
UNIQUE (publication_id, logical_unit_id),
-- Mỗi logical unit tối đa 1 version per publication (C1 I8).
-- Business rules (enforce via trigger/app):
-- 1. CONSISTENCY CONSTRAINT (bắt buộc):
-- unit_version.logical_unit_id PHẢI = publication_member.logical_unit_id.
-- Ngăn chặn: INSERT membership với logical_unit_id=A
-- nhưng unit_version thuộc logical_unit_id=B.
-- Enforce: trigger hoặc application validation tại INSERT/UPDATE.
--
-- 2. Khi publication.lifecycle_status = 'enacted':
-- a. unit_version.lifecycle_status PHẢI 'enacted' (CI-5).
-- b. logical_unit.lifecycle_status PHẢI 'active' (không retired).
-- Enacted publication không chứa retired logical_unit.
-- c. Membership LOCKED — block INSERT/UPDATE/DELETE.
--
-- 3. Khi publication.lifecycle_status = 'proposed':
-- a. MAY reference draft versions (C1A §9.2).
-- b. Membership có thể thay đổi.
--
-- 4. Thêm/xóa member từ enacted publication chỉ qua
-- publication version mới.
);
-- Indexes
CREATE INDEX idx_pm_publication ON publication_member(publication_id);
CREATE INDEX idx_pm_unit_version ON publication_member(unit_version_id);
5.5 section_type_vocab
-- PSEUDO-DDL — KHÔNG APPLY
-- Controlled vocabulary cho STRUCTURAL/GOVERNANCE metadata.
-- KHÔNG thay thế Đ24 taxonomy_facets / entity_labels.
-- Nếu cần pivot cross-system thì map/sync sang Đ24 bằng rule riêng.
CREATE TABLE section_type_vocab (
code TEXT PRIMARY KEY,
-- 17 candidates từ C1A §6: heading, article, paragraph,
-- definition, principle, rationale, process, technical_spec,
-- governance_process, checklist, instruction_block,
-- reference_mapping, matrix, invariant_list,
-- open_decision_list, appendix, changelog.
-- Council chốt chính thức.
name TEXT NOT NULL,
description TEXT,
lifecycle_status TEXT NOT NULL DEFAULT 'active'
CHECK (lifecycle_status IN ('active', 'deprecated', 'retired')),
owner TEXT,
-- Length thresholds per type (C1A §8.2)
soft_limit_words INTEGER DEFAULT 500,
hard_limit_words INTEGER DEFAULT 1500,
-- Override per section_type. instruction_block/appendix
-- cho phép cao hơn. Calibrate sau pilot data (OD-P5-09).
-- Birth gate config
description_required BOOLEAN DEFAULT TRUE,
-- Heading/container units MAY have description optional.
body_required BOOLEAN DEFAULT TRUE,
-- Heading/structural nodes MAY have body = NULL.
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
5.6 publication_type_vocab
-- PSEUDO-DDL — KHÔNG APPLY
-- Controlled vocabulary cho GOVERNANCE metadata.
-- KHÔNG thay thế Đ24 taxonomy_facets / entity_labels.
CREATE TABLE publication_type_vocab (
code TEXT PRIMARY KEY,
-- law, policy, sop, constitution, knowledge,
-- design_note, report, memo, draft, working.
name TEXT NOT NULL,
description TEXT,
lifecycle_status TEXT NOT NULL DEFAULT 'active'
CHECK (lifecycle_status IN ('active', 'deprecated', 'retired')),
-- Default risk tier per type (C1A §11.3)
default_risk_tier TEXT NOT NULL DEFAULT 'medium'
CHECK (default_risk_tier IN ('low', 'medium', 'high', 'highest')),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
5.7 change_set (hook)
-- PSEUDO-DDL — KHÔNG APPLY
-- Hook table — đủ để integration, chi tiết APR thuộc Đ32/P6
CREATE TABLE change_set (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Scope
publication_id UUID REFERENCES publication(id),
-- Publication chính đang sửa.
-- NULL nếu cross-publication change-set (OD-P5-05).
scope_description TEXT NOT NULL,
-- Self-contained (L5 §3.3).
-- Lifecycle
lifecycle_status TEXT NOT NULL DEFAULT 'draft'
CHECK (lifecycle_status IN (
'draft', 'submitted', 'review_passed',
'approval_passed', 'enacted', 'rejected', 'withdrawn'
)),
-- APR integration (Đ32)
apr_ref TEXT,
-- Opaque reference / FK tới APR system hiện hành.
-- Kiểu dữ liệu chính xác (UUID, INTEGER, TEXT...)
-- xác định ở integration design khi rà APR schema.
-- Tạo khi submitted.
-- Ownership
owner TEXT NOT NULL,
-- System auto
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
submitted_at TIMESTAMPTZ,
enacted_at TIMESTAMPTZ
);
5.8 change_set_member (hook)
-- PSEUDO-DDL — KHÔNG APPLY
CREATE TABLE change_set_member (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
change_set_id UUID NOT NULL REFERENCES change_set(id),
logical_unit_id UUID NOT NULL REFERENCES logical_unit(id),
-- What changed
change_type TEXT NOT NULL
CHECK (change_type IN (
'create', -- Tạo logical unit mới
'new_version', -- Tạo version mới cho enacted unit
'retire', -- Retire logical unit
'structural' -- Split/merge/re-parent
)),
old_version_id UUID REFERENCES unit_version(id),
-- Version trước thay đổi. NULL nếu create.
new_version_id UUID REFERENCES unit_version(id),
-- Version mới. NULL nếu retire.
-- Snapshot (C1 I9: đóng băng khi submitted)
snapshot_data JSONB,
-- Diff/evidence tại thời điểm submit.
-- Bất biến sau submitted.
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (change_set_id, logical_unit_id)
);
6. Relationship model
6.1 Quan hệ cấu trúc (cây dọc)
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Logical unit → parent | logical_unit.parent_id self-ref FK |
Parent cùng doc_code (I5). Trigger/app enforce. |
| Logical unit → document lineage | logical_unit.doc_code TEXT (KHÔNG FK) |
Structural binding. Validate bằng trigger/app kiểm doc_code tồn tại trong publication lineage registry / document_series / publication.doc_code set (deferred OD-P5-04). |
| Logical unit → children | Implicit qua parent_id + sort_order | Cây thuần, không DAG (I4). |
6.2 Quan hệ content (1:N)
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Logical unit → versions | unit_version.logical_unit_id FK |
1:N. Tối đa 1 enacted per logical_unit. |
6.3 Quan hệ publication (N:M)
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Publication → unit versions | publication_member junction |
UNIQUE per (publication_id, logical_unit_id). unit_version.logical_unit_id PHẢI = publication_member.logical_unit_id. |
| Một unit trong nhiều publications | Nhiều rows trong publication_member | Cho phép (LSL-01 §6.3). |
6.4 Quan hệ classification (N:M via Đ24)
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Logical unit → labels | entity_labels.entity_code = logical_unit.canonical_address (hoặc code mapping) |
Đ24 entity_labels junction. KHÔNG tạo table riêng (DP-3). |
6.5 Quan hệ ngang (horizontal / semantic)
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Unit ↔ unit (cross-doc) | universal_edges (existing) |
Tách biệt cây dọc (I4). Dùng universal_edges, KHÔNG dùng parent_id. |
| Successor (split/merge) | universal_edges với edge_type='succeeds' |
Ghi quan hệ cũ → mới khi split/merge. |
6.6 Quan hệ change governance
| Quan hệ | Cơ chế | Constraint |
|---|---|---|
| Change-set → members | change_set_member junction |
1:N. Liệt kê units thay đổi. |
| Change-set → APR | change_set.apr_ref opaque reference |
1:1 hoặc 1:0 (tạo khi submitted). |
| Change-set → publication | change_set.publication_id FK |
N:1. Thường 1 change-set gắn 1 publication. |
7. Lifecycle / Versioning model
7.1 Unit version lifecycle (per C1 §5.1)
draft ──[change-set enacted]──▶ enacted ──[version mới enacted]──▶ superseded
│ │
│ └──[logical_unit retire via CS+APR]──▶ retired
│
└──[sửa tại chỗ]──▶ draft (update in-place, chưa enacted)
Quy tắc chuyển trạng thái:
draft → enacted: CHỈ khi version nằm trong change-set đã enacted/applied.enacted → superseded: TỰ ĐỘNG khi version mới cho cùng logical_unit enacted.enacted → retired: CHỈ khi logical_unit bị retire qua change-set + APR. retired trên unit_version là hệ quả của retire logical_unit (C1 §6.4), không phải quyết định trên riêng version.- INV-RETIRE: Không được có
unit_version.lifecycle_status = 'retired'nếulogical_unit.lifecycle_status != 'retired'. Xem §15. - Không đi ngược. Enacted không quay draft. Sửa = version mới.
Trigger/app enforce:
- Trước enacted: kiểm version nằm trong change-set enacted.
- Khi enacted: set
enacted_at, auto supersede version cũ. - Enacted version: block UPDATE trên body/title/description/content_profile (immutability).
- retired: chỉ cho phép nếu logical_unit.lifecycle_status = 'retired'.
7.2 Logical unit lifecycle
draft_only ──[first version enacted]──▶ active
│
└──[retire via CS+APR]──▶ retired
draft_only: Mới tạo, chưa có version enacted.active: Có ≥1 version enacted.retired: Quyết định retire qua change-set + APR. Version enacted cuối → retired. Miếng hết hiệu lực.
Explicit column (không derived) để tránh query N versions mỗi lần check. DOT verify consistency.
7.3 Publication lifecycle
proposed ──[Council/Owner approve]──▶ enacted ──[version mới]──▶ superseded
│
└──[retire]──▶ retired
Quy tắc:
enacted: Membership (publication_member) bất biến. Chỉ enacted/current unit_versions + active logical_units (CI-5).superseded: Khi publication version mới enacted cho cùng doc_code.retired: Quyết định governance.
7.4 Change-set lifecycle
draft ──▶ submitted ──▶ review_passed ──▶ approval_passed ──▶ enacted
│
└──▶ rejected / withdrawn
Mapping với APR (C1 §5.4):
submitted: Tạo APR, snapshot đóng băng (I9).review_passed: Reviewers pass trên units.approval_passed: APR quorum đạt (Đ32).enacted: Apply step thành công → unit versions enacted, publication membership update.
7.5 Versioning scheme
Unit version: Sequential integer per logical_unit (version_number). Đơn giản, không ambiguous.
Publication version: Free-form text (semantic: '3.0', '4.6.3'). Publication version bump system-driven khi change-set enacted (C1 §6.5).
8. Label integration with Đ24
8.1 Mapping strategy
Logical unit classification labels sử dụng Đ24 entity_labels hiện có.
entity_labels (existing Đ24 table):
entity_code = logical_unit.canonical_address
(hoặc code mapping nếu entity_labels dùng format khác)
facet_code = 'doc' / 'topic' / 'layer' / 'family' / ...
label_value = 'D38' / 'segmentation' / 'law' / ...
8.2 Facets cần thiết cho logical_unit
| Facet | Mô tả | Ví dụ values | Status |
|---|---|---|---|
doc |
Document gốc | D38, D43, HP, SOP-DEPLOY | Cần kiểm Đ24 registry |
topic |
Chủ đề nội dung | segmentation, lifecycle, metadata | Cần kiểm Đ24 registry |
layer |
Tầng kiến trúc | law, design, implementation | Cần kiểm Đ24 registry |
family |
Nhóm tài liệu | law, policy, sop, knowledge | Có thể map từ publication_type |
Hành động P6: Rà soát Đ24 taxonomy_facets hiện hành. Facets nào đã tồn tại → dùng. Facets nào thiếu → đăng ký qua Đ24 + Council.
8.3 Phân biệt label doc=X vs publication membership
| Khía cạnh | Classification label doc=X |
Publication membership |
|---|---|---|
| Lưu ở | entity_labels (Đ24) |
publication_member |
| Ý nghĩa | "Miếng này nói về X" (phân loại/pivot) | "Miếng này là phần chính thức của PUB-X-v3.0-ENACTED" |
| Draft unit có thể có? | CÓ — draft unit vẫn có thể có label doc=D38 | KHÔNG trong enacted pub — draft unit KHÔNG nằm trong enacted publication. CÓ trong proposed pub. |
| Nhiều values? | CÓ — 1 unit có thể có doc=D38 VÀ doc=D43 | CÓ — 1 unit có thể nằm trong PUB-D38-v3.0 VÀ PUB-HP-v4.6.3 |
Đây là CI-4. Nhầm lẫn = bug nghiêm trọng.
8.4 section_type và vocabulary tables KHÔNG phải Đ24 label
section_type là unit metadata gắn logical_unit qua FK section_type_vocab. KHÔNG nằm trong entity_labels.
section_type_vocab và publication_type_vocab là controlled vocabulary cho structural/governance metadata, không thay thế Đ24 taxonomy_facets / entity_labels. Nếu cần query "tất cả miếng loại article" → JOIN logical_unit.section_type, KHÔNG query entity_labels.
Nếu tương lai cần section_type làm Đ24 facet (để pivot xuyên hệ thống) → tạo facet mới trong Đ24 + sync mechanism. Quyết định thuộc P6.
9. Publication / Membership rules
9.1 Enacted publication rules
-
Membership chỉ enacted/current versions + active logical_units (CI-5): Trigger/app kiểm:
unit_version.lifecycle_status = 'enacted'logical_unit.lifecycle_status = 'active'(không retired) Kiểm trước khi chuyển publication sang enacted.
-
Membership bất biến sau enacted (C1 I2, I9): Trigger/app block INSERT/UPDATE/DELETE trên
publication_memberkhipublication.lifecycle_status = 'enacted'. -
Mỗi logical unit tối đa 1 version per publication (C1 I8): UNIQUE constraint
(publication_id, logical_unit_id). -
Consistency constraint:
unit_version.logical_unit_idPHẢI =publication_member.logical_unit_id. Trigger/app enforce tại INSERT/UPDATE.
9.2 Proposed/draft publication
- MAY reference draft unit_versions (C1A §9.2).
- Membership có thể thay đổi khi publication đang proposed.
- Khi publication enacted → kiểm tất cả members: unit_version enacted + logical_unit active → lock membership.
9.3 Version bumping
Khi change-set enacted/applied cho 1 publication:
- Tạo publication version mới (doc_code giữ, version bump).
- Copy membership từ version cũ → version mới.
- Apply changes:
- Thêm unit_versions enacted mới.
- Loại unit_versions superseded CHỈ KHI đã có enacted replacement trong cùng logical_unit.
- KHÔNG include retired logical_units / retired unit_versions.
- Publication cũ →
superseded. - Publication mới →
enacted.
10. Vector projection hooks
10.1 Sync metadata trên unit_version
| Field | Mục đích | Loại |
|---|---|---|
vector_sync_status |
pending / synced / stale / error | System/DOT managed |
vector_synced_at |
Timestamp lần sync gần nhất | System auto |
vector_chunk_count |
Số canonical chunks hiện tại | Derived/cache |
10.2 Sync trigger points
| Event | Action |
|---|---|
| unit_version INSERT (draft) | Set vector_sync_status = 'pending' |
| unit_version content UPDATE (draft) | Set vector_sync_status = 'stale' → re-embed |
| unit_version enacted | Set vector_sync_status = 'pending' → re-embed |
| unit_version metadata-only update | Set vector_sync_status = 'stale' → update payload, KHÔNG re-embed |
| unit_version superseded/retired | Update Qdrant payload (mark status) |
10.3 Qdrant payload structure (concept)
Qdrant point payload inherit từ PG:
logical_unit_id,unit_version_idcanonical_address,doc_code,section_typelifecycle_status,version_number,owner- Classification labels (từ entity_labels)
chunk_id,span_start,span_end,chunk_index(projection metadata riêng)
PG = SoT, Qdrant = projection (LSL-01 §9.4). Drift → PG thắng.
10.4 Canonical chunk invariant
Mỗi canonical chunk nằm trong đúng 1 unit_version (CI-2). KHÔNG gộp nhiều unit_versions vào 1 chunk.
10.5 Chunk manifest — P6 hook
P5 cung cấp vector_chunk_count trên unit_version làm hook kiểm CI-2. Chi tiết chunk manifest thuộc P6 design, bao gồm:
- Chunk manifest table hoặc structure (chunk_id, unit_version_id, span_start, span_end, chunk_index, embedding_model, synced_at).
- Constraint: mỗi chunk row trỏ đúng 1 unit_version_id.
- DOT checker: verify chunk_count khớp manifest, verify không chunk nào gộp 2+ unit_versions.
P5 đảm bảo: hook đủ để P6 thiết kế manifest mà không cần sửa schema unit_version.
11. Review / Change-set / APR hooks
11.1 Review state trên unit_version
review_state field trên unit_version:
unreviewed→in_review→review_passed/review_failed→needs_re_review- Review parent ≠ approve children (I6). Không cascade.
- Reviewer (human hoặc agent) cập nhật review_state.
11.2 Change-set integration
change_set + change_set_member tables (§5.7, §5.8):
- Gom nhiều unit changes vào 1 change-set.
snapshot_datatrên change_set_member: đóng băng diff khi submitted (I9).- Lifecycle mapping với APR (§7.4).
11.3 APR integration
change_set.apr_refopaque reference tới APR system hiện hành (Đ32). Kiểu dữ liệu xác định ở integration design khi rà APR schema thực tế.- P5 KHÔNG redesign APR. Chỉ tạo hook (reference) để liên kết.
- Khi change-set submitted → tạo APR per Đ32 pipeline.
- Khi APR applied → change-set enacted → unit versions enacted.
11.4 Structural change-set
Split/merge/re-parent = change_type = 'structural' trong change_set_member:
- Split: 1 logical_unit retired + N logical_units mới created. Successor relation ghi trong
universal_edges(edge_type='succeeds'). - Merge: N logical_units retired + 1 logical_unit mới created. Successor relation ghi.
- Re-parent: update parent_id qua change-set. Canonical address KHÔNG đổi (LSL-01 §8.4).
12. Birth gate readiness
12.1 Birth logical_unit mới + draft version đầu tiên
| Check | Field(s) | Enforcement |
|---|---|---|
| Address unique | canonical_address UNIQUE constraint | BLOCK |
| Doc_code valid | doc_code tồn tại trong publication lineage registry / document_series / publication.doc_code set — deferred OD-P5-04 | BLOCK (trigger/app) |
| Parent valid | parent_id tồn tại + cùng doc_code | BLOCK (trigger/app) |
| Section_type valid | section_type FK section_type_vocab, status='active' | BLOCK |
| Owner present | owner NOT NULL | BLOCK |
| Title present | unit_version.title NOT NULL | BLOCK |
| Description present | unit_version.description — per section_type config | BLOCK hoặc PASS (section_type_vocab.description_required) |
| Body valid | body per section_type — heading/container OK if NULL | WARN hoặc PASS (section_type_vocab.body_required) |
| Required profile | identity_profile + content_profile chứa required fields per section_type config | BLOCK hoặc WARN (config) |
| Lifecycle default | logical_unit.lifecycle_status = 'draft_only', unit_version.lifecycle_status = 'draft' | SYSTEM AUTO |
| Timestamps | created_at, updated_at | SYSTEM AUTO |
| Sort_order | Giá trị hợp lệ | BLOCK |
| Content hash | content_hash computed | SYSTEM AUTO |
12.2 Birth version mới (cho enacted unit)
| Check | Field(s) | Enforcement |
|---|---|---|
| Logical unit exists | logical_unit_id FK valid | BLOCK |
| Version number | Auto-increment per logical_unit | SYSTEM AUTO |
| Title present | NOT NULL | BLOCK |
| Description | Per section_type config | BLOCK hoặc PASS |
| Body valid | Per section_type | WARN hoặc PASS |
| Required profile | Per section_type config | BLOCK hoặc WARN |
| Lifecycle default | 'draft' | SYSTEM AUTO |
| Review state | 'unreviewed' | SYSTEM AUTO |
| Content hash | Computed | SYSTEM AUTO |
12.3 Length check at birth
- Tính word count body → so sánh section_type thresholds (section_type_vocab.soft_limit_words / hard_limit_words).
- Set
length_flagtương ứng. - WARN, KHÔNG BLOCK draft (C1A §8.3, LSL-01 §11.2).
- Hard-limit → gate trước enacted (§8.4 C1A): bắt buộc 1 trong 3 decisions.
13. Open decisions còn lại
| Code | Câu hỏi | Đề xuất P5 v0.2 | Phase |
|---|---|---|---|
| OD-P5-01 | entity_labels entity_code format cho logical_unit | Dùng canonical_address. Nếu Đ24 dùng format khác → cần mapping table. | P5 v1 (rà Đ24 thực tế) |
| OD-P5-02 | Structural node (heading navigation, OD-C1A-09) cần unit_version không? | Đề xuất: CÓ, với body=NULL (section_type_vocab.body_required=FALSE). Giữ version history. | P5 v1 |
| OD-P5-03 | logical_unit.lifecycle_status explicit hay derived? | CHỐT: Explicit + DOT verify. | Chốt tại P5 |
| OD-P5-04 | doc_code binding: FK tới document_series riêng hay text + validate? | DEFERRED: hiện TEXT + trigger/app validate. Nếu cần FK → tạo document_series(doc_code PK). |
P5 v1 |
| OD-P5-05 | Cross-publication change-set | change_set.publication_id nullable. Bump versions cho mỗi publication liên quan. | P6 |
| OD-P5-06 | Retire cascade policy (C1-OD9) | Config per publication_type. Law = không auto cascade. Knowledge = warn + propose. | P6 |
| OD-P5-07 | Successor relation storage | Dùng universal_edges với edge_type='succeeds'. | P5 v1 |
| OD-P5-08 | Profile JSON Schema registry | Table riêng profile_schema_registry. |
P6 |
| OD-P5-09 | Length threshold calibration | Defaults: 500/1500. Override per section_type. | P6 |
| OD-P5-10 | publication.doc_code uniqueness | CHỐT: UNIQUE (doc_code, version). | Chốt tại §5.3 |
| OD-P5-11 | Extended lifecycle enum (withdrawn, archived) | Giữ C1 §5.1. Council mở rộng nếu cần. | P6 / C1 amend |
14. PASS criteria
| # | Criterion | Status |
|---|---|---|
| 1 | 2 bảng logical_unit + unit_version tách biệt — C1-OD12, C2-OD-M1 | ✅ DP-1 |
| 2 | Publication membership tách biệt label — C1A-OD-C1A-08 | ✅ DP-2 |
| 3 | Classification labels dùng Đ24 entity_labels — CI-9 | ✅ DP-3 |
| 4 | section_type = FK vocab, thuộc logical_unit, KHÔNG phải Đ24 label — IN-3, C2-OD-M8 | ✅ DP-4 |
| 5 | Vocab tables = structural/governance, KHÔNG thay thế Đ24 | ✅ DP-4 clarified |
| 6 | Profile metadata phân tầng — logical_unit / unit_version / publication | ✅ DP-5 |
| 7 | 7 invariants từ handoff đều được bảo toàn | ✅ §15 check |
| 8 | Pseudo-DDL đủ chi tiết cho GPT review — 8 tables | ✅ |
| 9 | Không apply SQL, không sửa luật, không DOT implementation | ✅ |
| 10 | Birth gate hooks rõ ràng — kiểm gì, block/warn per section_type config | ✅ §12 |
| 11 | Vector hooks + chunk manifest concept — sync status + P6 hook | ✅ §10 |
| 12 | Review/change-set/APR hooks — integration, apr_ref opaque | ✅ §11 |
| 13 | Open decisions liệt kê + đề xuất hướng | ✅ §13 (11 ODs) |
| 14 | doc_code = structural binding, KHÔNG FK vào non-unique | ✅ §5.1 |
| 15 | tier = derived/cache, không agent manual | ✅ §5.1 |
| 16 | content_hash bao gồm body+title+description+profile | ✅ §5.2 |
| 17 | INV-RETIRE invariant rõ ràng | ✅ §15 |
| 18 | publication_member consistency constraint | ✅ §5.4, §9.1 |
| 19 | Enacted pub kiểm cả logical_unit active | ✅ §9.1 |
| 20 | provenance map Đ24 FAC-PROV | ✅ §5.2 |
Constitutional check
| Nguyên tắc / Luật | Verdict | Ghi chú |
|---|---|---|
| NT1 / NT13 — PG là SoT | PASS | Nội dung authoritative ở PG. Qdrant = projection. |
| NT2 — Cơ chế máy | PASS có điều kiện | P5 = hooks. P6 phải thiết kế checker/birth gate thật. |
| NT4 — Config/registration path | PASS có điều kiện | Vocabulary/profile quản bằng config/governance, không hardcode. |
| NT11 — Khai tối thiểu | PASS | Tách logical_unit/unit_version giảm duplicate. Không registry song song. |
| Đ24 — Label Law | PASS | Label dùng entity_labels. Vocab tables ≠ Đ24 replacement. |
| Đ32 — APR | PASS | apr_ref hook, không redesign. |
| Đ33 — PG Law | PASS | Chưa apply SQL production. Chưa vượt gateway. |
| LSL-01 / C1A | PASS | Unit-centric giữ đúng. doc_code = structural binding. |
15. Invariants
| Code | Statement | Enforce by | Nguồn |
|---|---|---|---|
| INV-UNIT-SOT | Miếng thông tin là đơn vị SSOT nội dung nhỏ nhất | Architecture (2 tables) | NT15, CI-1 |
| INV-ENACTED-IMMUT | Enacted version bất biến — block UPDATE body/title/description/profile | Trigger/app | C1 I2 |
| INV-ADDRESS-IMMUT | Canonical address bất biến sau birth | UNIQUE + trigger block UPDATE | C1 I3, CI-6 |
| INV-PUB-NO-INLINE | Publication không chứa content inline — chỉ FK references | Table design (publication_member) | CI-3, LSL-01 §6.3 |
| INV-LABEL-NEQ-MEMBER | Label doc=X ≠ publication membership |
Tách biệt entity_labels vs publication_member | CI-4 |
| INV-ENACTED-PUB-ENACTED-ONLY | Enacted publication chỉ chứa enacted versions + active logical_units | Trigger/app kiểm trước enacted | CI-5 |
| INV-CHUNK-SINGLE-UV | Canonical chunk nằm trong đúng 1 unit_version | P6 manifest + vector_chunk_count hook | CI-2 |
| INV-NO-PARALLEL-REGISTRY | Label dùng Đ24, không tạo registry song song | Architecture (DP-3) | CI-9, P3 v0.4 |
| INV-SECTION-NOT-LABEL | section_type ≠ Đ24 classification label | FK vocab, tách entity_labels | IN-3 |
| INV-SINGLE-PARENT | Mỗi logical unit có đúng 1 canonical parent | parent_id self-ref, cây thuần | CI-11, I4 |
| INV-BIRTH-GATE | Mọi miếng mới qua birth gate, không đường tắt | Birth gate validation (§12) | CI-12, I7 |
| INV-PG-SOT-VECTOR | PG = SoT, Qdrant = projection. Drift → PG thắng. | Sync worker design | CI-10, LSL-01 §9.4 |
| INV-RETIRE | unit_version.lifecycle_status = 'retired' CHỈ hợp lệ khi logical_unit.lifecycle_status = 'retired'. retired trên version là hệ quả cascade từ retire logical_unit, không phải quyết định lifecycle độc lập. | Trigger/app enforce | C1 §6.4, GPT R2 #1 |
| INV-PM-CONSISTENCY | publication_member.logical_unit_id PHẢI = unit_version.logical_unit_id (via FK chain) | Trigger/app enforce | GPT R2 #3 |
| INV-PROVENANCE-VOCAB | provenance values phải map/tương thích Đ24 FAC-PROV. Agent không tự sáng tác. | Birth gate + DOT check | GPT R2 #6, Đ24 |
GPT Review Patch log
Round 1 (12 patches):
| # | Điểm | Hành động |
|---|---|---|
| 1 | doc_code = structural binding | ✅ Sửa comment §5.1 |
| 2 | Không FK doc_code vào non-unique | ✅ TEXT + validate, OD-P5-04 deferred |
| 3 | Đổi tên → publication_member | ✅ Mọi lifecycle |
| 4 | retired lifecycle | ✅ ĐIỀU CHỈNH: giữ per C1, clarify cascade, thêm INV-RETIRE |
| 5 | body_hash → content_hash | ✅ body+title+desc+profile |
| 6 | Profile phân tầng | ✅ identity/content/publication |
| 7 | Vector chunk manifest | ✅ vector_chunk_count + §10.5 |
| 8 | Vocabulary ≠ Đ24 | ✅ Ghi rõ |
| 9 | tier = derived | ✅ Ghi rõ |
| 10 | P6 ≠ DDL | ✅ Sửa §1 |
| 11 | apr_ref opaque | ✅ TEXT |
| 12 | Description exception | ✅ Per section_type config |
Round 2 (7 patches):
| # | Điểm | Hành động |
|---|---|---|
| 1 | INV-RETIRE invariant | ✅ §15 INV-RETIRE + enforce trong §5.2, §7.1 |
| 2 | §9.3 sửa câu loại superseded/retired | ✅ Chính xác hóa 3 bước apply |
| 3 | publication_member consistency constraint | ✅ §5.4 rule #1, §9.1 rule #4, §15 INV-PM-CONSISTENCY |
| 4 | Enacted pub kiểm logical_unit active | ✅ §5.4 rule #2b, §9.1 rule #1 |
| 5 | Birth gate doc_code valid wording | ✅ §12.1 deferred OD-P5-04 |
| 6 | provenance map Đ24 FAC-PROV | ✅ §5.2 + §15 INV-PROVENANCE-VOCAB |
| 7 | Constitutional check trong PASS criteria | ✅ §14 constitutional check table |
P5 Schema Draft v0.2 | S181 | 2026-04-26 | Opus 4.6 GPT Review: R1 PASS có điều kiện (12 patches) + R2 PASS có điều kiện nhẹ (7 patches) + Final PASS Chờ: User duyệt final → upload KB