S178 Fix 15 — Gói Amend Luật: DOT Repair Governance (v4 FINAL — SẴN SÀNG ENACT)
S178 Fix 15 — GÓI AMEND LUẬT: DOT REPAIR GOVERNANCE (v4 FINAL — SẴN SÀNG ENACT)
Ngày soạn v1: 2026-04-18 | v2: 2026-04-18 (post R1) | v3: 2026-04-18 (post R2) | v4 FINAL: 2026-04-18 (post R3) Phiên: S178 Fix 15 Trạng thái: FINAL — READY TO ENACT (sau Council Round 3 SIGN-OFF) Kết quả Round 3: Gemini 10/10 APPROVE FINAL | GPT 9.6/10 APPROVE WITH MINOR (5 minor apply inline, KHÔNG cần Round 4) Kết quả Round 2: Gemini 9.8 FINAL + P10/P11 | GPT 8.9 CHANGES + P10-P15 + evidence gap → merged vào v3. Phạm vi v4: Gói chạm 7 luật (HP + Đ22 + Đ32 + Đ33 + Đ35 + Đ36 register + Đ41 + Đ43) + 3 bảng mới + 3 ALTER.
5 minor apply so với v3 (GPT Round 3):
- M1:
admin_fallback_logthêmstatus,session_code, SLA 24hretroactive_apr_id(§II.P13).- M2: Quorum trigger khoá 3 edge case (§II.P14).
- M3: Chốt
app_lock vài phútlà production default (§II.P12).- M4: DB trigger chặn
handler_ref='unimplemented'(§II.P16).- M5:
version_verified_at+ snapshot JSON audit (§VIII).- Nit §3.1: Cấm rename PK code đang có lịch sử tham chiếu.
Thay đổi so với v2:
- OVERRIDE §3.1 P2 v2:
ON UPDATE CASCADE→ON UPDATE RESTRICT(GPT Round 2 – audit preservation thắng rename convenience).- Thêm 8 patch mới (P10-P17) từ cả 2 Council Round 2.
- Thêm §VIII verify base law enacted version (GPT Round 2 evidence gap).
- Amend §2 P2 §3.2: thêm
_dot_originvào 2 bảng type (Gemini P10 / Đ33+Đ35).- Update sơ đồ phụ thuộc + bảng §IV + §VI.
I. BỐI CẢNH (giữ nguyên v1)
I.1 Sự việc
Phiên S178 Fix 14 thực thi 4 cửa khai sinh luật cho Đ41+Đ43. Bước 4 (dot-nrm-enact) chặn câm do SQL query cột không tồn tại + 2>/dev/null nuốt lỗi. Agent tra luật → không luật nào cover flow "sửa bug DOT canonical đã enacted" → dừng đúng theo NT9.
I.2 4 lỗ hổng lộ ra
| # | Luật | Lỗ hổng |
|---|---|---|
| 1 | Đ41 v1.0 | Path /opt/incomex/dot/bin/ vô chủ |
| 2 | Đ32 v1.0 | proposed_action whitelist hardcode |
| 3 | Đ35 v5.1 | §5.2 nhắc fix_repair_dot không định nghĩa |
| 4 | Đ22 v1.0 | Silent-fail pattern lan rộng |
I.3 Triết lý gói amend
- Fix gốc, không vá triệu chứng (NT9).
- Giữ nguyên triết lý 4 cửa (Đ38 + Đ32).
- Áp NT4 triệt để: config > hardcode ở mọi cấp.
- Retrofit clause tách scope rõ, không đồng hạng deadline.
- Không atomic DB transaction — enact theo release train có barrier.
II. CÁC PATCH v3 (CŨ → MỚI)
PATCH P1 v2 — Đ41 v1.0 → v1.1: Mở rộng ops-code
(Giữ nguyên v2. Xem revision 2 cho chi tiết §2, §3.3, §5.8, §8 log schema với cột deploy_kind.)
PATCH P2 v3 — Đ32 v1.0 → v1.1: Whitelist PG-native + SCHEMA SPLIT + AUDIT-SAFE FK
§3.1 Schema approval_requests — SPLIT code khỏi payload + ON UPDATE RESTRICT (OVERRIDE v2):
ALTER TABLE approval_requests
ADD COLUMN request_type_code TEXT,
ADD COLUMN proposed_action_code TEXT;
ALTER TABLE approval_requests
ADD CONSTRAINT fk_apr_request_type
FOREIGN KEY (request_type_code) REFERENCES apr_request_types(request_code)
ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE approval_requests
ADD CONSTRAINT fk_apr_action_type
FOREIGN KEY (proposed_action_code) REFERENCES apr_action_types(action_code)
ON UPDATE RESTRICT ON DELETE RESTRICT;
Lý do RESTRICT (GPT Round 2): code được viện dẫn trong audit history. Cascade rename = ghi lại lịch sử = vi phạm audit integrity. Muốn đổi tên → tạo code mới, retire code cũ (status), backfill khi hợp lý.
§3.1.1 Nit Round 3 (GPT): Cấm rename trực tiếp PK code (action_code, request_code) khi code đó đã có bất kỳ row nào tham chiếu trong approval_requests. Enforce bằng trigger fn_prevent_code_rename_with_history:
CREATE OR REPLACE FUNCTION fn_prevent_code_rename_with_history()
RETURNS TRIGGER AS $$
BEGIN
IF OLD.action_code <> NEW.action_code THEN
IF EXISTS (SELECT 1 FROM approval_requests WHERE proposed_action_code = OLD.action_code) THEN
RAISE EXCEPTION 'Cannot rename action_code % — has % reference(s). Retire (status=retired) and create new code instead.',
OLD.action_code, (SELECT count(*) FROM approval_requests WHERE proposed_action_code = OLD.action_code);
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_apr_action_types_no_rename
BEFORE UPDATE ON apr_action_types
FOR EACH ROW EXECUTE FUNCTION fn_prevent_code_rename_with_history();
-- Trigger tương tự cho apr_request_types.
§3.2 Seed 2 bảng type (thêm _dot_origin — Gemini P10):
CREATE TABLE apr_action_types (
action_code TEXT PRIMARY KEY,
description TEXT NOT NULL,
handler_ref TEXT NOT NULL,
risk_level TEXT NOT NULL CHECK (risk_level IN ('low','medium','high')),
status TEXT NOT NULL CHECK (status IN ('active','deprecated','retired')),
_dot_origin TEXT NOT NULL, -- Đ33+Đ35 compliance: mọi bảng governance phải khai origin
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
retired_at TIMESTAMPTZ NULL
);
CREATE TABLE apr_request_types (
request_code TEXT PRIMARY KEY,
description TEXT NOT NULL,
default_action_code TEXT NULL REFERENCES apr_action_types(action_code)
ON UPDATE RESTRICT ON DELETE RESTRICT,
status TEXT NOT NULL CHECK (status IN ('active','deprecated','retired')),
_dot_origin TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
retired_at TIMESTAMPTZ NULL
);
Seed actions: create_item (low), update_item (low), add_field (medium), patch_ops_code (high), amend_law (high).
Seed request types: giữ 12 hiện hành + fix_repair_dot (default_action=patch_ops_code).
§3.3 Risk-level routing approval (xem P14 cho cơ chế enforce):
APR risk_level='high' → Council (2 AI + Chủ tịch). medium → Chủ tịch. low → fast-lane/auto.
§3.4 Đăng ký Đ36 Collection Protocol:
2 bảng type phải vào collection_registry + meta_catalog. DOT dot-apr-types-register (paired -audit).
§3.5 Legacy safety + sequencing:
8 bước migration bắt buộc. Cấm ON DELETE CASCADE; retire qua status='retired'.
PATCH P3 v2 — Đ35 v5.1 → v5.2: Flow fix_repair_dot
(Giữ nguyên v2. Xem revision 2 cho §6 6 bước, §6.4.1 verify 3 tầng, §6.5 ADMIN fallback, §5.3 paired test.)
PATCH P4 v2 — Đ22 v1.0 → v1.1: Cấm silent-fail + annotation
(Giữ nguyên v2. Xem revision 2 cho §4.1 3 mức + annotation markers, §4.2 DOT scan NT12, §4.3 retrofit 14/30/90.)
PATCH P9 v2 — HP v4.6.2 → v4.6.3: Định vị ops-code vào 3 lớp
(Giữ nguyên v2. Ops-code → Lớp Kho, instance của SSOT GitHub.)
PATCH P10 MỚI v3 — Đ33 v2.0 + Đ35 v5.2: Chuẩn hoá _dot_origin cho bảng governance mới (Gemini Round 2)
Bối cảnh: Đ33 §4 + Đ35 §4.1 yêu cầu mọi bảng governance/registry phải khai _dot_origin TEXT NOT NULL (tool sinh ra record đó).
Patch:
Bổ sung clause vào Đ35 §4.1: "Mọi bảng quản trị sinh ra bởi amend luật phải có cột _dot_origin TEXT NOT NULL. Amend Đ32 §3.2 (P2) đã tuân thủ."
Lỗi trước trong v2: 2 bảng type mới thiếu cột này → lặp lại chính bệnh Đ35 v5.1 đóng.
PATCH P11 MỚI v3 — Đ43 v1.2: Context pack bao phủ ops-code layer (Gemini Round 2)
Bối cảnh: Đ43 context pack §9 section_definitions chưa có entry cho ops-code. Agent đọc pack sẽ không thấy layer mới → về lâu dài tái vi phạm "AI không hiểu kiến trúc".
Patch:
Bổ sung 1 row vào context_pack_section_definitions:
- section_code:
ops_code_inventory - source_query: liệt kê DOT canonical + migration SQL + cron từ
dot_tools+ops_code_registry - max_size_bytes: 30000
Ghi nhận task: sau khi P1-P10 enact → tạo migration SQL nhỏ + regenerate pack.
PATCH P12 MỚI v3 — M2→M3 migration gate / dual-write (GPT P11 Round 2)
Rủi ro: Giữa M2 (backfill code columns) và M3 (deploy code mới đọc cột code), APR legacy có thể ghi bằng engine cũ (JSONB only) → row mới vào DB không có code → runtime mới fail.
Patch vào P2 §3.5:
Thêm bước 6b: "Triển khai dual-write compatibility trong dot-apr-propose phiên bản bridge: đồng thời ghi cả JSONB cũ và 2 cột code mới. Chạy 24h observation. Sau đó mới bật runtime mới (bước 6)."
Hoặc pha migration gate: đặt app_lock trong PG cấm INSERT vào approval_requests ngay sau backfill, cho đến khi runtime mới deploy xong (vài phút, không phải 24h).
CHỐT Round 3 (GPT M3): Production default = app_lock vài phút, KHÔNG dual-write 24h. Lý do: app_lock đơn giản, atomic, không cần code bridge dual-write (dễ drift). Dual-write 24h chỉ dùng nếu downtime vài phút không chấp nhận được (không phải case hiện tại).
Cụ thể:
-- Bước 5.5 (giữa backfill và deploy runtime mới):
BEGIN;
SELECT pg_advisory_lock(hashtext('apr_migration_lock'));
-- Deploy code mới. Nếu có INSERT APR nào đang chờ, sẽ block vài giây.
-- Sau khi code mới live:
SELECT pg_advisory_unlock(hashtext('apr_migration_lock'));
COMMIT;
Thời gian block expected: 10-60 giây. APR user-facing pending sẽ retry tự nhiên.
PATCH P13 MỚI v3 — ADMIN fallback audit schema (GPT P12 Round 2)
Rủi ro: §6.5 P3 v2 cho phép Chủ tịch bypass APR khi chính DOT APR hỏng — nhưng thiếu schema lưu dấu → NT10 thủng.
Patch vào Đ35 §6.5:
CREATE TABLE admin_fallback_log (
id BIGSERIAL PRIMARY KEY,
dot_code TEXT NOT NULL,
reason TEXT NOT NULL,
backup_path TEXT NOT NULL,
patch_diff TEXT NOT NULL,
verify_evidence JSONB NOT NULL, -- stdout/stderr/exit code 3 tầng
approved_by TEXT NOT NULL DEFAULT 'president',
session_code TEXT NOT NULL, -- M1 Round 3: bind phiên (S178-Fix15-...)
status TEXT NOT NULL DEFAULT 'applied'
CHECK (status IN ('applied','retroactive_documented','audit_overdue','rolled_back')), -- M1 Round 3
retroactive_apr_id BIGINT NULL REFERENCES approval_requests(id),
retroactive_deadline TIMESTAMPTZ NOT NULL
DEFAULT (NOW() + INTERVAL '24 hours'), -- M1 Round 3: SLA 24h
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- M1 Round 3: cron flip status sang audit_overdue nếu quá SLA mà chưa có retroactive APR
CREATE OR REPLACE FUNCTION fn_admin_fallback_overdue_scan()
RETURNS void AS $$
BEGIN
UPDATE admin_fallback_log
SET status = 'audit_overdue'
WHERE status = 'applied'
AND retroactive_apr_id IS NULL
AND NOW() > retroactive_deadline;
END;
$$ LANGUAGE plpgsql;
-- Cron hourly: SELECT fn_admin_fallback_overdue_scan();
Mọi ADMIN fallback fix phải INSERT row ở đây TRƯỚC KHI patch apply. retroactive_apr_id được điền sau khi tạo APR document hồi tố (trong 24h). Quá 24h → status='audit_overdue' → hệ thống tự động tạo system_issues kind='fallback_audit_overdue' cho Chủ tịch.
PATCH P14 MỚI v3 — High-risk quorum schema/flow (GPT P13 Round 2)
Rủi ro: §3.3 P2 v2 nói risk_level='high' → "Council (2 AI + Chủ tịch)" nhưng không có cơ chế enforce → text-only policy, dễ bypass.
Patch vào Đ32 §3.3:
CREATE TABLE apr_approvals (
id BIGSERIAL PRIMARY KEY,
apr_id BIGINT NOT NULL REFERENCES approval_requests(id) ON DELETE RESTRICT,
approver TEXT NOT NULL, -- 'president' | 'gemini' | 'gpt' | ...
approver_type TEXT NOT NULL CHECK (approver_type IN ('human','ai_council')),
decision TEXT NOT NULL CHECK (decision IN ('approve','reject','abstain')),
rationale TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (apr_id, approver)
);
Trigger fn_apr_quorum_check khi UPDATE approval_requests.status → 'approved': verify số row trong apr_approvals theo risk_level:
high: ≥1president+ ≥2ai_councilapprove, 0 reject.medium: ≥1presidentapprove.low: ≥1 approve bất kỳ (hoặc auto-rule).
Thiếu quorum → RAISE EXCEPTION → UPDATE bị chặn ở gốc DB, không phụ thuộc engine bash.
M2 Round 3 — Hardening 3 edge case (GPT):
-- (a) Self-approve prohibited: người propose không được tự approve APR của mình.
ALTER TABLE apr_approvals ADD CONSTRAINT chk_no_self_approve
CHECK (approver <> (SELECT proposer FROM approval_requests WHERE id = apr_id));
-- Hoặc check trong trigger nếu constraint subquery không hỗ trợ.
-- (b) Reject không được approve đè: nếu đã có 1 reject, mọi approve sau KHÔNG flip status.
-- Trong fn_apr_quorum_check: thêm điều kiện
-- IF EXISTS (SELECT 1 FROM apr_approvals WHERE apr_id = NEW.id AND decision = 'reject') THEN
-- RAISE EXCEPTION 'APR % has reject decision; cannot approve.', NEW.id;
-- END IF;
-- (c) Partial approve race: dùng row-level lock khi check quorum để tránh 2 approver cùng trigger transition.
-- SELECT * FROM approval_requests WHERE id = NEW.id FOR UPDATE;
-- Đặt ở đầu hàm trigger trước khi COUNT votes.
3 edge case đều xử lý ở trigger DB → không thể bypass bằng bash race.
PATCH P15 MỚI v3 — ALTER system_issues cho parent/children coalesce (GPT P14 Round 2)
Bối cảnh: v2 §4.1 P4 nói "coalesce via parent_issue_id" nhưng chưa verify cột này tồn tại. GPT flag đúng.
Patch:
ALTER TABLE system_issues
ADD COLUMN IF NOT EXISTS parent_issue_id BIGINT NULL
REFERENCES system_issues(id) ON DELETE SET NULL,
ADD COLUMN IF NOT EXISTS coalesce_key TEXT NULL;
CREATE INDEX IF NOT EXISTS idx_system_issues_parent ON system_issues(parent_issue_id);
CREATE INDEX IF NOT EXISTS idx_system_issues_coalesce ON system_issues(coalesce_key, status);
Scanner batch fill coalesce_key = md5(pattern || session_id) để nhóm. Issue đầu mỗi group là parent (parent_issue_id IS NULL), còn lại point về parent.
PATCH P16 MỚI v3 — Làm rõ amend_law action + verify Đ38 enacted (GPT P15 Round 2)
Bối cảnh: GPT flag evidence gap — KB file Đ38 là DRAFT v3.0, file Đ36 là DRAFT v5.0. Enacted versions (Đ38 v2.3, Đ36 v4.0) không có bản file riêng.
Xác minh của Chủ tịch (2026-04-18): HP v4.6.2 mục lục ghi Đ38 v2.3 enacted, Đ36 v4.0 enacted. File KB là bản DRAFT của phiên bản kế tiếp (v3.0 / v5.0 chưa enacted). Bản wording enacted nằm trong registry normative_registry.content_hash + rendered từ template Đ38 khi dùng.
Patch P16:
- Trong P2 §3.2 seed:
amend_lawaction — clarify là RESERVED cho flow Đ38 khi nâng cấpdot-nrm-amendactive. Hiện tại status='active' nhưng handler_ref='unimplemented' → APR dùng code này sẽ bị chặn ởdot-apr-executecho đến khi Đ38 cung cấp handler. - Ghi nhận nhu cầu: amend Đ38 trong tương lai để cung cấp
dot-nrm-amendcanonical (kế thừa patterndot-nrm-enact). KHÔNG làm trong gói này (scope creep). - Bổ sung §VIII verification: trước enact, agent phải query
normative_registryxác nhận Đ38 v2.3 + Đ36 v4.0 đang 'enacted' (không bump sang v3.0/v5.0 giữa chừng).
M4 Round 3 — DB gate (GPT): bổ sung trigger DB chặn handler chưa implement (không chỉ policy ở bash):
CREATE OR REPLACE FUNCTION fn_apr_block_unimplemented_handler()
RETURNS TRIGGER AS $$
DECLARE
handler TEXT;
BEGIN
SELECT handler_ref INTO handler
FROM apr_action_types
WHERE action_code = NEW.proposed_action_code;
IF handler = 'unimplemented' THEN
RAISE EXCEPTION 'Action % has handler_ref=unimplemented. Reserve-only, cannot execute.',
NEW.proposed_action_code;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_apr_block_unimplemented
BEFORE UPDATE ON approval_requests
FOR EACH ROW
WHEN (NEW.status = 'applied' AND OLD.status <> 'applied')
EXECUTE FUNCTION fn_apr_block_unimplemented_handler();
→ DB-first: dù bash dot-apr-execute có bug bypass, trigger DB vẫn chặn ở gốc.
PATCH P17 MỚI v3 — Chuẩn hoá naming file luật ENACTED vs DRAFT (tự rà Chủ tịch sau Round 2)
Rủi ro meta (GPT phát hiện): file dieu36-collection-protocol-law.md thực là DRAFT v5.0, không phải enacted v4.0 — gây nhầm. Nếu Council/agent đọc file này để rà chéo, sẽ rà vào bản chưa có hiệu lực.
Patch (ngoài scope gói này — ghi nhận, phiên riêng):
Convention mới cho file KB:
knowledge/dev/laws/dieu{N}-{name}-v{X}-enacted.md— bản có hiệu lực.knowledge/dev/laws/dieu{N}-{name}-v{Y}-draft.md— bản dự thảo.- Bỏ file không có hậu tố.
Retrofit: tạo symlink/alias trong KB, không đổi file vật lý (tránh phá refs cũ). Deadline: 30 ngày sau gói v3 enacted.
Không enact trong gói hiện tại — ghi nhận làm phiên S179 Convention Normalization.
III. PHỤ THUỘC GIỮA CÁC PATCH (v3)
P17 (convention file naming — NGOÀI GÓI, ghi nhận)
P9 (HP định vị ops-code)
↓
P1 (Đ41 ops-code layer + log schema)
↓
P15 (ALTER system_issues parent/coalesce) ──┐
P14 (apr_approvals quorum schema) ──┤
P13 (admin_fallback_log schema) ──┤ (3 schema song song)
↓ │
P2v3 (Đ32 PG-native + RESTRICT + _dot_origin)─┘
↓ (+ P10 _dot_origin standard, + P12 dual-write bridge)
P3 (Đ35 fix_repair_dot + verify 3 tầng + ADMIN fallback)
↓
P4 (Đ22 silent-fail + annotation + coalesce uses P15)
↓
P11 (Đ43 context pack ops-code section)
Thứ tự enact (governance): P9 → P1 → P13+P14+P15 (atomic) → P2 → P10 inline → P3 → P4 → P11.
Migration train có barrier:
- M1: P9 HP + P1 log schema + P13/P14/P15 schema alter (đều DDL, có thể cùng transaction).
- M2: P2 type tables + seed + backfill + P12 dual-write bridge + Đ36 register.
- M3: P3 runtime enable (flow + handlers).
- M4: P4 pha detect-only → enforce.
- M5: P11 context pack regenerate.
IV. CÂN BẰNG (v3)
| Tiêu chí | v1 | v2 | v3 |
|---|---|---|---|
| Số HP NT đóng | 4 | 6 | 7 (+ NT5 tự phát hiện qua P14/P15 schema gate) |
| Số luật chạm | 4 | 6 | 7 (+ Đ33 _dot_origin, + Đ43 P11) |
| Schema mới | 2 bảng | 2 bảng + 3 cột | 5 bảng mới/ALTER (+ apr_approvals, admin_fallback_log, system_issues ALTER) |
| DOT mới | 2 cặp | 4 cặp | 4 cặp (giữ) |
| Blocker technical | 0 đóng | 4 đóng | 8 đóng (+ CASCADE→RESTRICT, + _dot_origin, + dual-write, + audit schema, + quorum gate, + coalesce field) |
| Evidence gap (Đ36/Đ38) | — | — | Clarified ở §VIII |
V. CHECKLIST NT 3 TẦNG (v3)
- Tầng 1 code:
dot-apr-propose/executeđọc PG; scanner đọc registry;dot-apr-type-integrity-audit; bridge dual-write (P12). - Tầng 2 SQL DDL: 2 bảng type + 3 bảng mới (P13/P14/P15) + 3 ALTER (approval_requests, vps_deploy_log, system_issues); FK RESTRICT; CHECK; trigger quorum.
- Tầng 3 SQL data: Seed 5 actions + 13 request types +
_dot_origincho mọi row seed + backfill legacy idempotent. - Tầng 4 kiến trúc: P9 + P11 ops-code vào HP + Đ43 context pack.
VI. RÀ CHÉO LUẬT LIÊN QUAN (v3 cập nhật)
| Luật | Tương tác | Status v3 |
|---|---|---|
| HP v4.6.2 | Kiến trúc 3 lớp | → P9 đóng |
| Đ22 | Silent-fail enforce | → P4 v2 đóng |
| Đ32 | Schema split + quorum | → P2 v3 + P14 đóng |
| Đ33 v2.0 | _dot_origin chuẩn |
→ P10 đóng |
| Đ35 v5.1 | Flow fix_repair_dot + ADMIN fallback audit | → P3 + P13 đóng |
| Đ36 v4.0 enacted | Register 2 bảng type | → P2 §3.4 đóng (verify enacted ở §VIII) |
| Đ38 v2.3 enacted | amend_law reserved | → P16 clarify (verify §VIII) |
| Đ39 v2.3 | Shadow trigger binding | → Tự động, verify post-enact |
| Đ41 v1.0 | Ops-code layer | → P1 đóng |
| Đ43 v1.2 | Context pack ops-code | → P11 đóng |
VII. GHI CHÚ
- Đ35 v5.1 tham chiếu HP v4.5.1 → amend §6 bump sang v4.6.3 (sau P9 enact).
- Gói v3 scope 7 luật + 5 DDL mới. Round 3 scope hẹp: verify base version + final sign-off.
- Sau enact → tiếp tục S178 Fix 14 khai sinh Đ41+Đ43.
- Drift toàn registry (HP/Đ35/Đ36/Đ38) ghi nhận phiên S179 riêng (kèm P17 naming).
VIII. VERIFY BASE LAW ENACTED VERSION (MỚI v3 — GPT Round 2 evidence gap)
Rủi ro: File KB dieu36-*.md là v5.0 DRAFT, dieu38-*.md là v3.0 DRAFT. Nhưng HP v4.6.2 mục lục ghi Đ36 v4.0 enacted, Đ38 v2.3 enacted. Gói này amend dựa trên wording enacted, không phải DRAFT.
Yêu cầu bắt buộc TRƯỚC khi enact gói v3:
Agent/CLI phải chạy truy vấn:
SELECT code, version, status, content_hash, enacted_at
FROM normative_registry
WHERE code IN ('NRM-LAW-32','NRM-LAW-33','NRM-LAW-35','NRM-LAW-36','NRM-LAW-38','NRM-LAW-43','NRM-CON-HP')
ORDER BY code;
Verify:
- NRM-LAW-36 = v4.0 enacted.
- NRM-LAW-38 = v2.3 enacted.
- Các luật khác khớp HP v4.6.2.
Nếu registry không khớp HP → DỪNG, mở phiên rà drift (S179) trước khi enact gói hiện tại. Nếu khớp → tiếp tục.
Nguồn wording enacted chuẩn: normative_registry.content_hash + template render Đ38, KHÔNG đọc file .md DRAFT.
M5 Round 3 — Audit snapshot (GPT): lưu bằng chứng verify vào bảng chuyên dụng, không chỉ chạy query rồi quên:
CREATE TABLE IF NOT EXISTS law_version_verification_log (
id BIGSERIAL PRIMARY KEY,
session_code TEXT NOT NULL,
amend_package_id TEXT NOT NULL, -- vd: 'S178-Fix15-DOT-Repair-Governance'
snapshot JSONB NOT NULL, -- toàn bộ kết quả query §VIII
hp_version_at_time TEXT NOT NULL,
verified_by TEXT NOT NULL,
verified_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
verdict TEXT NOT NULL CHECK (verdict IN ('match','drift_detected','halt'))
);
Agent enact gói PHẢI INSERT 1 row ở đây trước khi chạy M1 migration. snapshot field chứa full kết quả query registry. Sau này audit chỉ cần join admin_fallback_log / apr_approvals về row này.
HẾT v4 FINAL. Council Round 3 SIGN-OFF (Gemini 10/10 FINAL + GPT 9.6/10 MINOR inline đã apply). SẴN SÀNG ENACT.