KB-BE1E

Review Hội đồng AI — Dự thảo sửa luật Track A Đ43 Phase C (Vòng 1)

14 min read Revision 1
councilreviewtrack-adieu43dieu3dieu4dieu35dieu24round1gpt2026-04-20

Review Hội đồng AI — Dự thảo sửa luật Track A Đ43 Phase C (Vòng 1)

  • Ngày: 2026-04-20
  • Agent: Incomex Hội đồng AI (GPT)
  • Phạm vi: review dự thảo cụ thể sửa Đ3 + Đ35 + Đ4 + Đ24
  • Tài liệu chính: knowledge/current-state/reports/du-thao-sua-luat-track-a-d43-phase-c.md
  • Căn cứ đã đọc:
    • knowledge/current-state/reports/dinh-huong-sua-luat-d43-phase-c.md
    • knowledge/current-state/reports/council-synthesis-d43-phase-c-round1.md
    • knowledge/dev/laws/law-03-metadata.md
    • knowledge/dev/laws/law-04-birth-process.md
    • knowledge/dev/laws/dieu35-dot-governance-law.md
    • knowledge/dev/laws/label-law.md
    • knowledge/dev/laws/constitution.md
    • knowledge/dev/laws/dieu29-classification-law.md

1) Phán quyết tổng

Verdict: APPROVE WITH CHANGES

Điểm: 8.8/10

  • Đúng hướng chiến lược: 9.3
  • Độ chặt chẽ pháp lý: 8.8
  • Khả thi kỹ thuật: 8.4
  • Tuân HP/NT: 8.8
  • Sẵn sàng enact sau sửa nhỏ: 8.7

Nhận định chính

Bản dự thảo đã biến định hướng vòng trước thành cơ chế thực thi khá rõ ràng: Đ3 đặt baseline machine-checkable, Đ35 đặc tả DOT, Đ4 enforcement tại birth, Đ24 bổ sung provenance tối thiểu. Đây là cấu trúc đúng, đơn giản, PG-first, config-driven và chưa sa đà vào phức tạp hóa Track B.

Tuy nhiên, hiện còn 2 lỗi thiết kế mức HIGH4 chỉnh sửa mức MEDIUM cần xử lý trước khi coi là bản đủ chặt để ban hành.


2) Hai lỗi HIGH phải sửa trước khi thông qua

HIGH-1 — governance_role IS NULL => bỏ qua là hở cửa

Trong fn_description_birth_guard(), logic hiện tại là:

  • nếu collection_registry không tìm thấy record cho TG_TABLE_NAME thì _gov_role IS NULL
  • hàm RETURN NEW và bỏ qua enforcement

Đây là một lỗ hổng thật vì:

  • trái tinh thần Đ29: collection chưa được quản lý đầy đủ thì phải coi là chưa đáng tin, không phải được miễn kiểm tra âm thầm
  • trái NT9: không chắc đúng thì không được lặng lẽ cho qua
  • tạo incentive xấu: bảng mới thiếu registry entry sẽ bypass guard

Khuyến nghị sửa:

  • NULL không được coi như excluded
  • hành vi đúng nên là:
    • mode rollout: log issue loại missing_collection_registry_entry và WARN rõ ràng
    • mode stable / block: RAISE EXCEPTION yêu cầu đăng ký collection trước
  • Tối thiểu phải tách rõ 2 trường hợp:
    • excluded = miễn thật
    • NULL/not found = lỗi quản trị, không phải miễn

HIGH-2 — Trigger tự INSERT INTO system_issues có nguy cơ recursion/nhiễu

Thiết kế hiện tại log warning trực tiếp trong trigger bằng cách ghi system_issues. Điều này có 3 rủi ro:

  1. Nếu system_issues cũng có description và sau này bị xếp governed/observed, có thể tạo vòng lặp hoặc nhiễu chồng nhiễu.
  2. Trigger mức row-level trên INSERT/UPDATE mà mỗi vi phạm lại ghi issue mới có thể gây issue flood khi backfill diện rộng.
  3. Hàm guard sinh side-effect ghi thêm dữ liệu vận hành, làm tăng coupling và khó debug.

Khuyến nghị sửa:

  • Không log trực tiếp vào system_issues trong trigger row-level.
  • Thay bằng một trong hai cách:
    1. Preferred: RAISE WARNING + để H11/phased scanner gom và ghi issue tổng hợp.
    2. Hoặc: ghi vào bảng chuyên biệt nhẹ kiểu governance_events / validation_events có dedupe key, và bảng này phải explicit EXEMPT.

Nếu vẫn muốn giữ system_issues, phải có đủ guard:

  • explicit không gắn trigger cho system_issues
  • dedupe key (source_table, source_id, issue_class, status='open')
  • chống insert trùng mỗi lần UPDATE

3) Trả lời 7 câu hỏi

Câu 1 — Machine-checkable đủ chưa?

Kết luận: Đủ cho Track A, nhưng nên thêm 1 check rất rẻ nữa.

Hiện tại:

  • C1 NOT NULL/non-empty
  • C2 length >= 30
  • C3 tiếng Việt có dấu (spot-check)

Mình đánh giá cho Track A như vậy là hợp lý. Không nên nhảy sang NLP/regex semantic quá sớm.

Khuyến nghị thêm 1 check nhẹ:

  • Trim trước khi kiểm: btrim(description) <> ''
  • Và tính độ dài trên bản đã trim: length(btrim(description)) >= _min_len

Lý do:

  • tránh chuỗi toàn khoảng trắng vượt C1 giả
  • giữ logic cực đơn giản, PG-native, ít false positive

Không khuyến nghị ở Track A:

  • regex bắt buộc có từ khóa
  • keyword detection
  • kiểm tra “tiếng Việt có dấu” bằng regex PG

Những thứ đó dễ brittle và nên để spot-check / Track B.

Câu 2 — DOT min length 50 vs baseline 30 hợp lý?

Kết luận: Hợp lý. Giữ 50.

Lý do:

  • DOT phải chứa mục đích + trigger/output + paired → cần dài hơn entity thường
  • 50 ký tự là mức tối thiểu vừa đủ để buộc người viết không ghi kiểu “script chạy APR”
  • 80 hoặc 100 ở giai đoạn này có thể gây khó chịu rollout mà chưa chắc tăng chất lượng thật

Khuyến nghị:

  • giữ baseline=30, dot=50
  • khi ổn định vài tuần mới xem có cần nâng DOT lên 60/80 không, dựa dữ liệu thực

Câu 3 — fn_description_birth_guard lookup collection_registry theo TG_TABLE_NAME có đúng bảng?

Kết luận: Đúng hướng, nhưng default behavior hiện sai.

Lookup bằng collection_registry WHERE collection_name = TG_TABLE_NAME là hợp lý vì:

  • Đ29 định nghĩa collection_registry là nơi quản trị collection-level với governance_role
  • tránh tạo map mới, hợp NT1

Nhưng phải sửa default:

  • not found không được coi là EXEMPT
  • phải coi là governance error

Đề xuất default behavior:

  • rollout phase: WARN + event/log riêng “collection chưa đăng ký”
  • stable phase: BLOCK luôn vì bảng chưa registry là vi phạm Đ29/Đ4

Khuyến nghị bổ sung trong luật:

  • trigger chỉ được gắn cho bảng đã có entry hợp lệ trong collection_registry
  • migration rollout phải kiểm tra coverage trước khi create trigger

Câu 4 — Provenance facet FAC-PROV hay gắn vào facet hiện có?

Kết luận: Tạo FAC-PROV mới là đúng hơn.

Lý do:

  • provenance là trục nghĩa riêng, không phải domain, role hay source nghiệp vụ thông thường
  • ép vào facet hiện có sẽ làm mơ hồ semantics của facet đó
  • cardinality single rất hợp cho provenance state hiện tại

Lưu ý:

  • mô tả của FAC-PROV nên nói rõ là provenance của description/metadata generation state, không phải provenance tuyệt đối của toàn entity trong mọi ngữ cảnh
  • nếu về sau mở rộng provenance sâu hơn, Track B có thể tách thêm relation/provenance graph, nhưng Track A làm facet là đủ gọn

Câu 5 — 16 bảng governed gắn trigger — danh sách đúng?

Kết luận: Tạm ổn, nhưng không nên đóng cứng danh sách trong luật/dự thảo theo kiểu manual.

Vấn đề:

  • chính draft cũng nói nguồn truth là collection_registry WHERE governance_role='governed'
  • nếu vậy, danh sách 16 bảng nên coi là snapshot triển khai, không phải truth pháp lý cứng

Nhận xét từng nhóm:

  • dot_tools, collection_registry, table_registry, dot_operations, dot_domain_rules, meta_catalog, law_jurisdiction, binding_registry, taxonomy, taxonomy_facets, modules, universal_rule_registry → hợp lý
  • dot_config → nên cân nhắc kỹ nhưng mình vẫn nghiêng giữ trigger, vì config governance mà không có description thì về lâu dài rất khó vận hành
  • context_trigger_sources → hợp lý nếu thật sự governed và có description
  • entity_species → cần kiểm tra semantics, vì nếu đây là bảng mapping/junction thì description có thể không phải field bản chất. Nếu có description thật thì OK; nếu không phải entity mô tả độc lập thì không nên ép
  • dot_coverage_required → tương tự, cần xác minh đây là entity governed thật hay bảng support/constraint

Khuyến nghị chốt:

  • Trong luật: quy định theo tiêu chí “mọi bảng governed có cột description”
  • Trong migration/report: liệt kê snapshot 16 bảng tại thời điểm enact
  • Xác minh lại riêng 2 bảng: entity_species, dot_coverage_required

Câu 6 — Rủi ro trigger loop (R1) đã xử lý chưa?

Kết luận: Chưa xử lý đủ.

Nếu trigger WARN bằng cách INSERT system_issues, thì loop/nhiễu là rủi ro thật, kể cả khi hôm nay system_issues chưa nằm trong 16 bảng governed.

Lý do:

  • trạng thái governance của system_issues có thể đổi về sau
  • ngay cả không loop vô hạn, vẫn có nguy cơ spam issues mỗi lần update

Khuyến nghị xử lý dứt điểm:

  • bỏ INSERT system_issues khỏi trigger row-level
  • thay bằng RAISE WARNING hoặc event table exempt riêng có dedupe
  • nếu bất khả kháng vẫn dùng system_issues, phải ghi luật rõ: system_issuesexcluded, trigger guard không bao giờ gắn vào đó, và có unique/open-issue dedupe

Câu 7 — PG-first alignment có lệch không?

Kết luận: Nhìn chung aligned tốt với PG-first.

Các điểm đúng:

  • config nằm trong dot_config
  • enforcement bằng PG trigger/function
  • provenance dùng entity_labels
  • policy axis dùng collection_registry.governance_role

Điểm còn lệch nhẹ / cần nói rõ hơn:

  • phần NT3 hiện draft ghi “write path Directus API” hơi hẹp. Nếu write path hợp pháp là DOT/Directus/PG function có audit thì nên viết rộng hơn, tránh vô tình ràng buộc sai kiến trúc.
  • notes ghi “bảng chưa có extra_metadata thì ghi cuối description” là giải pháp tạm chấp nhận được, nhưng về lâu dài hơi pha trộn semantics. Track A chấp nhận, nhưng nên ghi rõ đây là transitional workaround.

4) Rủi ro/lỗ hổng bổ sung ngoài 7 câu hỏi

R1 — Trigger trên UPDATE OF description có thể bị lách qua UPDATE khác cột

Nếu app/update path sửa row nhưng không đụng cột description, trigger UPDATE OF description sẽ không fire. Điều này có thể chấp nhận cho bài toán “guard khi viết/sửa description”, nhưng không phải guard toàn trạng thái hàng.

Khuyến nghị:

  • giữ như draft cho Track A là được
  • nhưng phải ghi rõ mục tiêu: guard tại INSERTkhi chỉnh description, không phải re-validate mọi UPDATE

R2 — COALESCE(NEW.code, NEW.id::text, 'unknown') không chắc hợp lệ cho mọi bảng

Không phải bảng nào cũng có cả code hoặc id. Trong PL/pgSQL trigger generic, truy cập field không tồn tại có thể lỗi compile/runtime nếu viết trực tiếp.

Đây là lỗi kỹ thuật cần sửa.

Khuyến nghị sửa:

  • dùng to_jsonb(NEW)->>'code'to_jsonb(NEW)->>'id' để đọc động, tránh phụ thuộc schema từng bảng
  • hoặc bỏ source_id ở trigger warning path nếu chưa có helper an toàn

R3 — description_min_length đang áp chung cả DOT nếu hàm không override theo bảng

Draft Đ35 đặt dot_description_min_length=50, nhưng hàm Đ4 mẫu hiện tại mới chỉ đọc description_min_length, chưa có nhánh override cho dot_tools.

Đây là mismatch giữa luật và implementation mẫu.

Khuyến nghị sửa:

  • trong function: nếu TG_TABLE_NAME='dot_tools' thì đọc dot_description_min_length, ngược lại dùng baseline
  • hoặc tổng quát hơn: bảng nào có threshold override trong config thì dùng override

R4 — notes chưa có nơi lưu nhất quán ngoài extra_metadata

Đ3 thêm notes là hợp lý, nhưng phần “bảng chưa có extra_metadata thì ghi cuối description” chỉ nên là giải pháp quá độ.

Khuyến nghị:

  • ghi rõ trong luật: notes là metadata mở rộng tùy nơi lưu hợp pháp; Track A chưa bắt buộc schema-wide
  • tránh để người đọc hiểu nhầm notes đã là field chuẩn trên mọi bảng

R5 — PROV-HUMAN đang gộp “human-written” và “human-reviewed”

Hai trạng thái này khác nghĩa:

  • human trực tiếp viết
  • human chỉ review AI output

Track A chưa cần tách, nhưng câu mô tả nên nói rõ PROV-HUMAN = “human-authored hoặc human-reviewed-and-approved” để tránh hiểu sai.


5) Kiểm tra 13 NT Hiến pháp

PASS

  • NT1 SSOT: dùng governance_roleentity_labels, không đẻ map riêng → PASS
  • NT2 Tự động: trigger/function/config → PASS
  • NT4 Config-driven: min length + mode trong dot_config → PASS
  • NT7 Dual-trigger: birth guard + H11 → PASS
  • NT10 PG over text: rule được kéo về PG-enforceable/config/queryable → PASS
  • NT11 Khai tối thiểu: tái dùng hệ đang có → PASS
  • NT12 DOT theo cặp: H11 làm động cơ phụ giám sát → PASS
  • NT13 PG native: trigger/function/config là PG-first → PASS

PASS CÓ ĐIỀU KIỆN

  • NT3 DOT 100% (có ngoại lệ): PASS nếu ghi rõ: AI là ngoại lệ ở pha suy luận; pha ghi dữ liệu phải qua write path hợp pháp có audit, không nhất thiết chỉ Directus API.
  • NT9 Không chắc đúng = sai: hiện draft có nguy cơ vi phạm nếu giữ gov_role NULL => bỏ qua. Sửa điểm này thì PASS sạch.

Không thấy vi phạm rõ

  • NT5, NT6, NT8 không có dấu hiệu vi phạm trực tiếp trong phạm vi sửa này.

6) Khuyến nghị sửa cụ thể trước vòng 2

Bắt buộc sửa

  1. Đổi logic gov_role IS NULL từ “bỏ qua” thành “governance error” (WARN/BLOCK theo phase).
  2. Bỏ INSERT system_issues trực tiếp trong trigger hoặc thêm guard/dedupe rất chặt nếu vẫn giữ.
  3. Sửa cách lấy source_id để không phụ thuộc cột code/id tồn tại vật lý trên mọi bảng.
  4. Thêm override threshold cho dot_tools để thực thi đúng Đ35 (50 ký tự).

Nên sửa

  1. Dùng btrim(description) thay vì description != ''.
  2. Chuyển danh sách 16 bảng thành snapshot triển khai, còn quy tắc luật là “mọi bảng governed có cột description”.
  3. Mô tả PROV-HUMAN rõ hơn để bao cả authored/reviewed-approved.
  4. Viết rộng lại NT3 write path: “đường ghi hợp pháp có audit” thay vì chỉ “Directus API”.

7) Kết luận ngắn cho Chủ tịch

Đây là bản dự thảo tốt và gần đủ để ban hành, đúng tinh thần “đơn giản, machine-checkable, config-driven”. Tôi không đề nghị reject. Nhưng hiện tại chưa nên approve thẳng vì còn một số lỗ hổng thi công cụ thể ở trigger logic.

Phán quyết cuối:

  • APPROVE WITH CHANGES
  • Điểm: 8.8/10
  • Sau khi sửa 4 điểm bắt buộc ở mục 6, bản này có thể lên khoảng 9.2–9.4/10 và sẵn sàng cho vòng review tiếp theo / enact nhẹ.
Back to Knowledge Hub knowledge/current-state/reports/council-review-draft-track-a-d43-phase-c-round1-gpt-2026-04-20.md