KB-2021

Council Review — Đ35 v5.1 DRAFT — GPT Round 1

17 min read Revision 1
council-reviewdieu35v5.1gptround1

Council Review — Đ35 v5.1 DRAFT — GPT Round 1

Tóm 1 câu

APPROVE WITH CHANGES: hướng sửa là đúng và xử trúng 4 RC, nhưng còn 4 blocker wording/kỹ thuật cần chốt trước khi ban hành để khỏi rơi vào kiểu “luật đúng ý nhưng máy không chạy đúng”.

Câu 1 — Xung đột HP

Kết luận

Không thấy xung đột hiến pháp mức bác bỏ. Ngược lại, v5.1 đang vá đúng các lỗ hổng làm v5.0 chưa thực hiện trọn HP. Tuy nhiên có 3 điểm cần sửa wording để khỏi tự va vào NT7, NT9, NT11.

Evidence chính

  1. NT1 — Làm một lần, dùng mãi:
    • HP v4.5.1 và Điều 1 nói rõ SSOT duy nhất, sửa 1 chỗ dùng mãi.
    • Đ35 v5.1 §11 thêm retrofit clause cho entity cũ, nhằm chặn pattern “luật chỉ đúng với row mới, row cũ lệch vĩnh viễn”. Đây là đúng tinh thần NT1.
    • Handoff S177 §3.2 xác nhận RC-1: fn_birth_gate chỉ soi row mới, 272 DOT cũ không retrofit; nên nếu không có §11 thì legacy sẽ vênh mãi.

Đánh giá: §11 đủ đúng hướng, nhưng chưa đủ lực pháp lý nếu chỉ viết “Đ36, Đ37, Đ38, Đ39, Đ41 và luật sau phải có §retrofit tương tự”. Cần ghi rõ: mọi luật đã ban hành mà đang tác động bảng có data cũ nhưng chưa có retrofit thì phải mở amend bắt buộc trong đợt gần nhất. Nếu không, NT1 mới chỉ bảo vệ luật tương lai, chưa khóa nợ cũ.

  1. NT2 + NT5 — Tự động 100%, tự phát hiện tự sửa:

    • Đ22 §1 yêu cầu vòng khép kín: nhận diện → ghi system_issues → xử lý → xác nhận → cải tiến.
    • Đ35 v5.1 §8.1 H10-H13 + §8.1 khoản escalation bắt buộc qua fn_log_issue()đúng HP, vì biến DOT health từ “biết lỗi nhưng im lặng” thành “biết lỗi và đẩy vào hệ thống”.
    • Handoff S177 §3.2 RC-4 cho thấy curl || true đã làm “cảnh sát câm”, nên amend này là hợp hiến, không xung đột.
  2. NT7 — Dual-trigger:

    • Điều 1 và Điều 0-H đều yêu cầu thực thể quan trọng có trigger chính + trigger phụ.
    • Đ35 v5.1 §5 bước 4 thiết kế đúng mô hình: dot-dot-registerđộng cơ chính, flow [AUTO-ID] DOT Toolslưới đỡ phụ.

Nhưng có 1 chỗ cần sửa: flow [AUTO-ID] hiện đang là PATCH backfill sau khi row đã được tạo. Nếu sau này bật NOT NULL/birth_gate_mode='block', row thiếu metadata có thể bị chặn ngay ở DB và flow phụ không còn cơ hội cứu. Nghĩa là dual-trigger chỉ mạnh ở giai đoạn warn, yếu đi khi sang block.

Cần wording lại: trigger phụ phải được định nghĩa là pre-submit inference hoặc repair path độc lập, không chỉ “PATCH sau khi insert thành công”. Nôm na: lưới đỡ phải đặt trước hố chứ không đặt dưới đáy hố.

  1. NT4 — Sẵn sàng thay đổi:

    • HP/Điều 1 yêu cầu thay đổi bằng metadata/config thay vì hardcode.
    • V5.1 thay CHECK hardcode bằng FK + dot_config.birth_gate_mode; đây là đúng hướng NT4.
    • Handoff S177 §3.2 RC-2 xác nhận 4/5 fields đang dùng CHECK hardcode, nên sửa này là cần thiết.
  2. NT10 — Quản lý bằng PG:

    • Điều 1 NT10: thông tin máy cần validate/query/enforce phải nằm trong PG.
    • V5.1 đưa operation/trigger_type/coverage_status/file_path và mode vào bảng/FK/config PG; hợp hiến.
  3. NT11 — Khai tối thiểu:

    • Điều 1 NT11 cấm khai lại thứ PG đã tự biết.
    • V5.1 bắt payload 10/10 fields ở §5.4 là hợp lý với operation, trigger_type, coverage_status, _dot_origin; nhưng với file_path, cron_schedule, thậm chí một phần domain, nếu dot-dot-register đã suy luận được từ disk + config thì luật nên nói rõ “payload tối thiểu ở API boundary, nhưng nguồn gốc ưu tiên là suy luận tự động từ PG/config/disk; không ép người khai tay”.
    • Nếu không nói rõ, người đọc dễ hiểu thành “phải khai tay đủ 10 field”, hơi cấn NT11.
  4. NT9 và NT13:

    • NT9: bản draft phần lớn tuân thủ vì có grace, verify rồi mới bật NOT NULL.
    • NT13: trong HP v4.5.1 hiện hành tôi không thấy NT13; bản hiện hành đang nêu 11 NT. Vì vậy tôi không dùng NT13 làm căn cứ pháp lý. Điểm này nên ghi rõ để tránh viện dẫn sai số điều.

Kết luận câu 1

  • Pass hiến pháp về hướng kiến trúc.
  • Cần sửa 3 điểm:
    1. §11 phải ràng buộc cả luật đã ban hành nhưng chưa retrofit, không chỉ luật tương lai.
    2. NT7 dual-trigger phải mô tả trigger phụ theo cách vẫn sống được khi DB chuyển sang block.
    3. Wording §5.4 phải tránh hiểu thành “khai tay 10/10”, để không cấn NT11.

Câu 2 — Xung đột luật khác

Kết luận

Không thấy xung đột cứng; có 3 điểm cần làm rõ ranh giới.

1. Với Đ0-G Birth Registry

  • Đ0-G quy định mọi entity sinh ra phải có birth record, trigger chủ yếu xử lý row mới, còn backfill/inspection là DOT riêng.
  • Đ35 v5.1 không phủ định Đ0-G; ngược lại đang sửa đúng lỗ Đ0-G bị lộ ở DOT layer: fn_birth_gate warning-only và thiếu retrofit.
  • Handoff S177 §3.5 xác nhận có 6 DOT birth-related đã tồn tại nhưng chưa chạy; nên §11.3 của v5.1 là triển khai tinh thần Đ0-G, không xung đột.

Điểm cần làm rõ: tên fn_birth_gate trong draft đang dùng để chặn metadata DOT trên dot_tools. Tên này dễ gây hiểu nhầm sang “birth registry gate” của Đ0-G. Nên đổi tên pháp lý/kỹ thuật thành kiểu fn_dot_metadata_gate hoặc ghi rõ đây là gate cho DOT birth/registration path, không phải gate chung của mọi collection.

2. Với Đ0-H 5 tầng

  • Đ0-H §2 nói DOT là cổng duy nhất; §4 nói có động cơ chính và động cơ phụ.
  • Đ35 v5.1 củng cố đúng tinh thần này: dot-dot-register là cổng chính, health + flow là lưới đỡ.
  • Không thấy conflict.

Nhưng cần giữ ranh giới: flow [AUTO-ID] là cơ chế phụ trong Directus, không được biến thành nguồn sự thật mới ngoài PG/dot_tools.

3. Với Đ22 Self-healing

  • Đ22 §1-§4 yêu cầu mọi phát hiện phải ghi system_issues và được phơi bày ra ánh sáng.
  • Đ35 v5.1 §8.1 escalation bắt buộc qua fn_log_issue()đấu nối đúng với Đ22.
  • Không conflict; đây là chỗ mạnh nhất của draft.

4. Với Đ26 Pivot

  • Đ26 yêu cầu đếm bằng pivot/đếm trực tiếp, và quản trị bằng metadata.
  • V5.1 bổ sung metadata completeness rate §7.6 là tương thích.
  • Không conflict.

5. Với Đ31 Toàn vẹn

  • Đ31 ưu tiên “phát hiện trước, fix sau”, coverage metrics, watchdog và system_issues.
  • H10-H13 phù hợp tinh thần Đ31.
  • Tuy nhiên, Đ31 phân biệt CRITICAL/WARNING/INFO và 2-pass verify cho warning. V5.1 nên ghi rõ H10-H11 sau grace mà vẫn ở warning hay critical theo tiêu chí nào, để severity nhất quán với Đ31.

6. Với Đ32 APR

  • Đ32 yêu cầu approval request phải đứng được một mình và là đường chính cho thay đổi có tác động.
  • Đ35 v5.1 tạo APR cho classify/pairing/fix là phù hợp.
  • Không conflict.

Cần làm rõ: trường hợp DOT_<LAW>_BACKFILL tự backfill hàng loạt theo infer rule có cần APR trước không, hay chỉ APR khi “không suy luận được”. Draft hiện chọn cách này ở §11.2.1, và tôi thấy hợp lý; nên ghi thêm một câu: auto-backfill chỉ áp cho transform xác định, idempotent, có verify pair; mơ hồ thì APR.

7. Với Đ36 Collection Protocol

  • Đ36 draft dùng Birth Registry, species mapping, collection governance và APR làm nền; Đ35 chỉ quản trị DOT phục vụ các thứ đó.
  • Không thấy overlap phá nhau.
  • §11 retrofit của Đ35 nên áp ngược được cho Đ36 vì Đ36 cũng là luật đụng bảng đã có data cũ.

8. Với Đ41 VPS Code Operation

  • Đ41 v1.0 §5, §8, §9 yêu cầu deploy có lock, verify, log PG, known-good và DOT guard.
  • Đ35 v5.1 là luật nội dung/kiến trúc cho DOT; Đ41 là luật vận hành/triển khai trên VPS. Hai luật bổ sung, không đè nhau.
  • Phụ lục Đ41 §13.5 còn ghi rõ thứ tự bắt buộc là amend Đ35 v5.0 → v5.1 trước, rồi mới triển khai. Nghĩa là Đ41 đang nhường đường cho Đ35, không conflict.

Trả lời trọng tâm: §11 retrofit áp ngược được không?

Theo wording hiện tại: áp được về nguyên tắc, nhưng chưa đủ chặt về cơ chế cưỡng chế.

  • §11.1 nói “mọi luật mới áp dụng cho bảng có data cũ bắt buộc kèm DOT retrofit”. Câu này thiên về luật mới.
  • §11.4 có thêm “Đ36, Đ37, Đ38, Đ39, Đ41 và luật sau phải có §retrofit tương tự”, tức là đã hé cửa cho luật đã ban hành.

Nhưng để hết mơ hồ, cần sửa thành câu cứng hơn:

“Mọi luật đang có hiệu lực mà tác động bảng có data cũ nhưng chưa có retrofit clause đều phải mở amend bổ sung retrofit trong kỳ sửa gần nhất; trước khi amend xong, không được bật constraint/block mới làm legacy kẹt cứng.”

Nôm na: luật cũ cũng phải quay lại dọn sân nhà mình, không được bảo “từ nay về sau em sẽ gọn”.

Câu 3 — Khả thi kỹ thuật

Kết luận chung

Khả thi trên PG16, nhưng có 4 chỗ phải test/chốt trước production.

Khoản 1 — UNIQUE partial(file_path) + NOT NULL 5 cột

  • UNIQUE partial index trên PG16: chạy được bình thường.
  • ALTER COLUMN ... SET NOT NULL trên 5 cột: chạy được, nhưng sẽ lock/scan bảng khi apply; với 272 row thì nhỏ, khả thi.
  • Rủi ro thật không nằm ở SQL mà ở thứ tự chạy:
    1. dedupe duplicate file_path
    2. fill metadata
    3. audit = 0 drift
    4. rồi mới bật NOT NULL/index

Blocker wording: draft đang nói partial index “để cho phép row grace period vẫn tồn tại”, nhưng index không cho phép duplicate non-null dù đang grace. Nó chỉ cho phép NULL tồn tại. Câu này nên sửa cho chính xác, kẻo người đọc hiểu nhầm khả năng của index.

Khoản 2 — H10-H13 + escalation qua fn_log_issue()

  • Về kiến trúc là đúng.
  • Về kỹ thuật, dùng PG function thay HTTP call là tốt hơn curl || true.
  • Nhưng hiện draft mới nêu tên fn_log_issue(), chưa định nghĩa contract tối thiểu: tham số gì, dedupe thế nào, SECURITY DEFINER hay invoker, ghi vào DB nào.
  • Nếu chưa có function này trong hệ hiện tại, ban hành nên kèm phụ lục/DDL stub tối thiểu.

Khoản 3 — fn_birth_gate mode configurable qua dot_config.birth_gate_mode

  • CREATE OR REPLACE FUNCTION ... LANGUAGE plpgsql SECURITY DEFINER là hợp lệ trên PG16.
  • Đọc mode từ dot_config là đúng NT4.

Concern 1: fn_is_in_grace_period()

  • Tôi không tìm thấy bằng chứng function này đã tồn tại trong Agent Data/search hiện có.
  • Vì vậy, trạng thái đúng theo NT9 là: không chắc — coi như chưa có.
  • Khuyến nghị: trong luật phải ghi rõ 1 trong 2 cách:
    • hoặc định nghĩa luôn fn_is_in_grace_period() trong §9 bootstrap,
    • hoặc bỏ function này, thay bằng inline query đọc grace_period_days + law_enacted_at/created_at rõ ràng.

Concern 2: _dot_origin

  • Draft dùng NEW._dot_origin; cần chắc dot_tools thực sự có cột này trong schema sống. Nếu không có thì function sẽ fail compile/execute.
  • Trong draft §4.1 bảng 10 fields lại không liệt kê _dot_origin, nhưng §5.4 payload có _dot_origin, và §8.3 kiểm tra _dot_origin. Đây là một lệch nội bộ ngay trong luật.
  • Đây là blocker lớn nhất về kỹ thuật/documentation: _dot_origin là field chính thức của dot_tools, hay chỉ field tạm ở API/path? Phải chốt 1 cách.

Concern 3: SECURITY DEFINER

  • SECURITY DEFINER hữu ích để trigger/function vẫn ghi được system_issues hoặc đọc dot_config dù caller quyền thấp.
  • Nhưng phải khoá search_path cố định bên trong function, nếu không có nguy cơ search_path hijack. Draft chưa nói.
  • Khuyến nghị wording: mọi SECURITY DEFINER function phải SET search_path = public (hoặc schema chỉ định) và owner là role vận hành chuẩn.

Khoản 4 — §11 retrofit clause

  • Về mặt kỹ thuật: hoàn toàn khả thi nếu 6 DOT đã tồn tại thật như handoff S177 §3.5 nói.
  • Điểm chưa chắc: DOT_METADATA_FILL “backfill từ file content + naming + git history” nghe đúng hướng, nhưng phần “git history” có thể không ổn định khi VPS-as-SSOT theo Đ41, vì không phải thay đổi nào cũng có Git sạch/đủ. Nên xem “git history” là nguồn phụ, không phải nguồn bắt buộc.

Cần test gì trước production?

  1. Test compile/runtime của fn_birth_gate với đủ case:
    • thiếu 1 field,
    • thiếu nhiều field,
    • warn + trong grace,
    • warn + hết grace,
    • block + hết grace.
  2. Test duplicate file_path migration với 45 cặp hiện có:
    • dedupe trước,
    • tạo index sau,
    • verify không crash.
  3. Test flow [AUTO-ID] + DB gate:
    • khi warn, flow có backfill kịp không;
    • khi block, flow có bị chặn từ cửa DB không.
  4. Test escalation path:
    • H10-H13 có thực sự vào system_issues không,
    • dedupe issue có bắn bão không.
  5. Test race/idempotency cho 6 DOT retrofit chạy liên tiếp hoặc lặp lại.

Câu 4 — Rủi ro vận hành

1. Grace period 7 ngày có đủ cho retrofit 272 DOT không?

Không chắc đủ; thiên về hơi ngắn nếu còn phải xử 45 cặp duplicate + 6 DOT chưa từng chạy.

  • 272 row thì ít về số lượng.
  • Nhưng việc khó là suy luận đúng, dedupe đúng, và verify 0 drift.
  • Nếu 7 ngày là grace mặc định toàn hệ, vẫn chấp nhận được; nhưng với lần ban hành này nên có quyền gia hạn bằng config hoặc theo đợt.

Khuyến nghị: giữ mặc định 7 ngày trong dot_config, nhưng wording thêm:

“Không được chuyển sang block và không bật NOT NULL nếu DOT_METADATA_AUDIT còn drift; grace có thể kéo dài bằng config mà không cần sửa luật.”

2. Mặc định birth_gate_mode='warn' có đủ an toàn để ban hành luôn không?

Có, với điều kiện đi kèm 2 chốt:

  1. escalation vào system_issues phải thật sự hoạt động;
  2. có tiêu chí chuyển warnblock rõ ràng.

Nếu không có tiêu chí, warn dễ biến thành “cảnh báo vĩnh viễn”, lặp lại RC-1.

Khuyến nghị chốt tiêu chí chuyển block:

  • 0 duplicate file_path
  • DOT_METADATA_AUDIT = 0 drift trong X ngày
  • flow [AUTO-ID] ACTIVE
  • verify H10-H13 pass liên tục

3. UNIQUE partial(file_path): nếu 45 cặp đang cùng trỏ 1 file thì patch sao không crash?

Không được tạo index trước khi dedupe. Trình tự an toàn nên là:

  1. snapshot danh sách duplicate,
  2. chọn canonical row cho mỗi file_path,
  3. row dư thì retire/merge/null tạm file_path,
  4. verify hết duplicate,
  5. mới tạo unique index.

Draft hiện có nói partial index “cho phép row grace period vẫn tồn tại mà không crash 45 cặp duplicate hiện có”, câu này không đúng kỹ thuật nếu 45 cặp đang đều non-null. Đây là blocker wording cần sửa.

Có khả năng có, nhất là giữa:

  • DOT_BIRTH_BACKFILL
  • DOT_METADATA_AUDIT
  • DOT_METADATA_FILL

Nếu chạy đồng thời, audit có thể đọc trạng thái nửa chừng và báo drift giả; backfill/fill có thể đụng cùng row. Với 272 row thì rủi ro không lớn về tải, nhưng lớn về logic.

Khuyến nghị:

  • chạy tuần tự có barrier theo §11.3: backfill → audit → fill → audit lại,
  • hoặc dùng advisory lock/lease để mỗi DOT biết đang có đợt retrofit.

Nôm na: 6 người vào dọn kho cùng lúc không hẳn nhanh hơn; dễ thành người này vừa xếp, người kia đã ghi biên bản “kho còn bừa”.

Câu 5 — Đề xuất cải thiện

Blocker

  1. Chốt _dot_origin là field chính thức hay không.

    • Hiện §4.1 không liệt kê, §5.4 và §8.3 lại dùng. Phải thống nhất.
  2. Sửa câu về partial unique index.

    • Index không cứu được duplicate non-null hiện hữu. Nó chỉ cho phép nhiều NULL, không cho phép nhiều non-null trùng.
  3. Định nghĩa hoặc bỏ fn_is_in_grace_period().

    • Không có bằng chứng function này đã tồn tại.
  4. Viết lại dual-trigger để còn đúng khi mode=block.

    • Flow PATCH-after-insert không đủ là lưới đỡ dài hạn.

Non-blocker nhưng nên sửa

  1. Đổi tên fn_birth_gate hoặc chú thích rõ phạm vi.

    • Tránh nhập nhằng với gate của Đ0-G cho birth_registry/governed collections.
  2. Thêm tiêu chí chuyển warnblock.

    • Ví dụ: audit 0 drift trong 3 ngày liên tiếp + flow active + 0 duplicate file_path.
  3. Bổ sung yêu cầu SECURITY DEFINER an toàn.

    • SET search_path cố định, owner chuẩn, grant tối thiểu.
  4. Bổ sung rule APR cho auto-backfill.

    • Infer chắc chắn/idempotent thì auto-fix; không chắc thì APR.
  5. Sửa wording §11 thành meta-rule áp cả luật đã ban hành.

    • Không chỉ “luật tương lai”, mà cả Đ36/37/38/39/41 đã sống cũng phải có amend retrofit.
  6. Ghi rõ thứ tự BLOCK 4 bằng checklist cứng:

  • dedupe file_path
  • chạy backfill/fill
  • audit=0
  • mới bật NOT NULL/index/block

Có nên tách §11 thành luật riêng?

Chưa nên tách ở thời điểm này.

  • Vì bệnh hiện tại là bệnh của chính Đ35 và DOT registry.
  • Tách meta-law lúc này sẽ đúng về mỹ học nhưng chậm chữa bệnh.
  • Nên để §11 nằm trong Đ35 v5.1 để xử ca cấp cứu, rồi sau khi hệ ổn mới nâng thành meta-law chung kiểu “luật hồi tố bắt buộc”.

Nôm na: đang cháy bếp DOT thì gắn bình cứu hỏa ngay trong bếp trước; sau mới tính viết giáo trình phòng cháy cho cả toà nhà.

Điểm số 1-10

8.3/10

Blocker

  1. _dot_origin lệch giữa §4.1 và §5/§8.
  2. fn_is_in_grace_period() chưa có bằng chứng tồn tại.
  3. Câu mô tả UNIQUE partial hiện sai kỹ thuật với duplicate non-null.
  4. Dual-trigger hiện chưa đứng vững khi mode chuyển sang block.

Non-blocker

  1. Chưa có tiêu chí cứng chuyển warnblock.
  2. Chưa nói rõ chuẩn an toàn cho SECURITY DEFINER.
  3. §11 nên viết cứng hơn để bao trùm cả luật đã ban hành.