Council Round 2 — GPT — Điều 38 v2.0
Council Round 2 — GPT — Điều 38 v2.0
Điểm tổng thể
8.9/10 — THÔNG QUA.
v2.0 đã sửa đúng gần như toàn bộ các lỗ khóa gốc của v1.0. Hạt nhân giờ đã đủ chặt để ban hành: temporal model chuẩn PG hơn, binding không còn tự do, precedence đã được data hóa, snapshot policy đã rõ, compatibility với Điều 37 đã được kéo về hạ tầng thay vì lời nói. Phần còn lại chủ yếu là tinh chỉnh để tránh trượt nghĩa khi triển khai, không còn là lỗi kiến trúc gốc.
11 sửa — đã đúng và đủ chưa?
Nhìn chung: ĐÚNG.
- 1. tstzrange + EXCLUDE: đúng hướng, là nâng cấp chuẩn nghề thật sự.
- 2. binding_registry: đúng, khóa gốc tốt hơn hẳn formula tự do.
- 3. precedence engine: đúng và cần thiết. Đây là sửa quan trọng nhất để máy “phân xử” được.
- 4. snapshot policy: đúng, và đã kéo kiến trúc từ “có thể đúng” sang “không được mơ hồ”.
- 5. Điều 37 compatibility view: đúng. Chặn được 2 SSOT song song.
- 6. section_id + schema_version: đúng.
- 7. +sql_query +enum_ref: đúng, tăng sức biểu đạt thật sự.
- 8. shadow ban: đúng hướng, nhưng cần làm rõ điều kiện block để tránh false positive.
- 9. indexing strategy: đúng.
- 10. partition document_instances: đúng.
- 11. migration 2 pha: đúng và thực tế.
Cần sửa thêm 4 điểm nhỏ trước freeze hoặc ghi rõ ngay trong luật/appendix kỹ thuật:
resolve_effective()hiện đang dùngscope_summary ILIKE '%topic%'là chưa đủ chuẩn machine-readable. Đây chỉ nên là fallback tạm thời, không phải cơ chế lõi lâu dài.binding_registry.binding_typehiện mới có(field/view/query)nhưng section types đã cóenum_ref. Nên hoặc bổ sungenum/taxonomy, hoặc quy địnhenum_refdùngview/fieldnào.valid_periodGENERATED từ 2 UI fields là ổn, nhưng trigger 10 “sync valid_period” trở nên thừa/mơ hồ nếu cột là generated stored. Nên chọn một cơ chế duy nhất.template_code FK→normative_registrynên chặn rõ chỉ được tham chiếudoc_type='template', không phải bất kỳ normative nào.
Trả lời 10 câu hỏi
1. tstzrange + EXCLUDE: GENERATED column từ 2 UI fields có vấn đề gì với Directus? Có nên dùng trigger thay GENERATED?
Đánh giá: Giữ GENERATED STORED là tốt hơn trigger, miễn Directus chỉ ghi valid_from và valid_until. PG tự tính valid_period sẽ ít drift hơn trigger.
Điểm cần chốt: nếu đã dùng generated column thì không cần trigger sync nữa. Trigger chỉ nên giữ cho validation bổ sung, không dùng để “đồng bộ lại” thứ PG đã tự sinh.
2. binding_registry: Có cần thêm binding_type ngoài field/view/query? Approval flow cho binding mới — DOT hay APR?
Đánh giá: Có, nên thêm ít nhất enum hoặc taxonomy để phản ánh đúng enum_ref. Nếu không, semantics bị lệch.
Về approve: binding mới nên qua APR (Điều 32) + DOT thực thi, không nên chỉ DOT tự tạo. Lý do: binding là “điểm nối luật ↔ data sống”, rủi ro cao hơn thêm config thường.
3. resolve_effective(): Logic doc_level thấp = thắng có đủ chưa? Ngoại lệ nào?
Đánh giá: Đủ làm nguyên tắc chung, nhưng chưa đủ làm engine cuối cùng nếu chỉ dựa category + scope_summary ILIKE.
Ngoại lệ cần tính:
- văn bản cấp thấp hơn nhưng là specialized exception cho một phạm vi con
- văn bản cùng level nhưng khác authority/department
- superseded hoặc blocked nhưng vẫn còn record enacted cũ
- thời gian hiệu lực giao nhau có rule chuyển tiếp
Kết luận: rule phân xử là đúng; hàm hiện tại còn quá mỏng. Nên xem resolve_effective() hiện là v1 engine, và roadmap phải chuyển từ text search sang scope/binding/relation-based resolution.
4. Snapshot policy: Có cần partial snapshot hay all-or-nothing đủ?
Đánh giá: Với hợp đồng/văn bản gửi ra ngoài, all-or-nothing sau sign là đúng và đủ.
Partial snapshot chỉ nên cho giai đoạn trước sign hoặc cho report nội bộ tái sinh nhiều lần. Không nên đưa partial snapshot vào luật lõi v2.0 nếu chưa có taxonomy rõ, vì sẽ tăng độ mơ hồ.
Kết luận: giữ all-or-nothing là đúng cho v2.0.
5. Điều 37 VIEW read-only có ảnh hưởng gì đến 5 bảng Điều 37 khác khi đổi FK source?
Đánh giá: Không có vấn đề kiến trúc nếu làm đúng hướng: FK thật phải trỏ về normative_registry, còn law_registry chỉ là compatibility view cho code cũ đọc.
Điểm phải chốt: không được để bất kỳ bảng mới nào của Điều 37 tiếp tục FK vào law_registry view. View chỉ để đọc tương thích, không phải relational anchor.
6. 9 section types đã đủ chưa? Thiếu loại nào cho business rules thực tế?
Đánh giá: Đủ cho v2.0. 9 loại hiện tại đã bao được phần lớn use case.
Loại còn thiếu nhưng chưa bắt buộc ngay là workflow_ref / approval_ref. Tôi xem đây là bổ sung phase sau, nhất là khi Điều 34 và approval matrix machine-readable chín hơn.
7. Shadow Ban: Auto-block khi mâu thuẫn cấp trên — quá mạnh hay đúng mức?
Đánh giá: Đúng mức, với điều kiện trigger block chỉ áp cho xung đột cấu trúc chắc chắn, không áp cho nghi ngờ mơ hồ.
Tôi không khuyên thêm “warning trước block” ở PG nếu conflict là rõ ràng; vì như vậy sẽ mở cửa cho VB sai lọt vào enacted/review pipeline.
Nhưng nên chia 2 mức:
- hard block: conflict chắc chắn theo binding/range/precedence
- warning / review required: conflict nghi ngờ do text/ngữ nghĩa
8. Migration 2 pha: Pha 1 import 22 luật dạng text section rồi chuẩn hóa dần — có rủi ro gì?
Đánh giá: Có rủi ro, nhưng là rủi ro chấp nhận được và ít rủi ro hơn ép chuẩn hóa giả ngay từ đầu.
Rủi ro chính là “PG có text blob nên người ta tưởng đã structured”. Cách chặn là:
- gắn cờ
schema_version='legacy-import'hoặcnormalization_status='raw_text' - không cho dùng các luật raw-text này vào advanced automation (binding/impact chi tiết) nếu chưa chuẩn hóa
9. Scale: 3 collections + 13 triggers + 1 EXCLUDE có quá phức tạp cho single VPS?
Đánh giá: Không quá phức tạp cho quy mô mục tiêu 2500 VB + vô hạn instances trên single VPS.
Điểm nhạy cảm không phải số lượng trigger, mà là chất lượng trigger. Nếu trigger nhỏ, đơn nhiệm, index đúng, hoàn toàn chịu được.
Điểm cần để mắt là:
- render pipeline Carbone/PDF
- growth của
document_instances - query JSONB/binding impact nếu không index tốt
10. Còn thiếu gì để ban hành?
Đánh giá: Không còn thiếu gì ở mức “chặn ban hành”. Còn 4 việc nên chỉnh ngay hoặc ghi rõ hơn:
- bỏ trigger sync
valid_periodnếu đã dùng generated stored - thêm
binding_type='enum/taxonomy' - chặn
template_codechỉ được tham chiếu template docs - ghi rõ
resolve_effective()hiện là engine v1, chưa phải cuối cùng nếu còn phụ thuộcscope_summary
Rủi ro còn lại nếu ban hành v2.0
resolve_effective()còn phụ thuộc text (scope_summary ILIKE) → có nguy cơ cho kết quả đúng cú pháp nhưng yếu nghĩa khi scale.- binding semantics chưa hoàn toàn khít nếu không bổ sung enum/taxonomy type.
- raw-text import ở pha 1 có thể làm mọi người ảo giác rằng 22 luật đã structured hoàn toàn.
document_instancespartition theo rendered_at là đúng, nhưng cần bảo đảm draft records không bị dồn vào null partition vô tổ chức.- shadow ban nếu viết trigger quá rộng sẽ tạo false block, làm vận hành khó chịu.
Kết luận
THÔNG QUA.
Đây là bản đã vượt ngưỡng “thông qua có điều kiện” của vòng 1. Nó đã khóa gần hết các lỗ gốc mà v1.0 còn hở. Tôi xem v2.0 là đủ chuẩn để ban hành trên stack hiện tại.
Mức sẵn sàng ban hành
8.9/10
4 chỉnh sửa nhỏ tôi muốn chốt trước khi freeze
- Bỏ mơ hồ giữa GENERATED
valid_periodvà trigger sync. - Bổ sung
binding_type='enum/taxonomy'. - Chặn
document_instances.template_codechỉ tớidoc_type='template'. - Ghi rõ
resolve_effective()hiện là precedence engine v1; phase sau nên chuyển sang scope/binding-based resolution thay vì text ILIKE.