KB-6455

Council Review — Gói DOT Repair Governance v3 — Round 3 — GPT

9 min read Revision 1
council-reviewgptround3s178-fix15dot-repair-governancefinal-signoffminor-inline

Council Review — Gói DOT Repair Governance v3 — Round 3 — GPT

Ngày: 2026-04-18 | Điểm v3: 9.6/10 | Phán quyết: APPROVE WITH MINOR

1. Tóm tắt

v3 đã đóng gần hết các hở kỹ thuật của Round 2 và đủ gần mức FINAL; phần còn lại chỉ là minor inline fixes, không cần Round 4 nếu apply ngay trong cùng PR.

2. Xác nhận chung

  • P10 CASCADE → RESTRICT: đúng ý tôi và đúng hướng audit-preservation.
  • P12 race M2→M3: đã chạm đúng bệnh, nhưng cần chốt 1 option production thay vì để mở 2 nhánh.
  • P13 admin_fallback_log: đúng hướng NT10, chỉ cần siết thêm 2 constraint nhỏ.
  • P14 apr_approvals + trigger quorum: rất tốt, nhưng trigger nên khóa thêm 3 edge case.
  • P15 system_issues ALTER: idempotent đủ cho replay.
  • P16 amend_law RESERVED: đúng triết lý, nhưng cơ chế chặn phải có DB gate, không chỉ engine bash.
  • §VIII verify base law version: đúng và cần thiết; nên thêm dấu thời gian verify để audit.

3. Technical sign-off — 7 điểm

3.1 §3.1 RESTRICT

Kết luận: ĐÚNG Ý TÔI.

ON UPDATE RESTRICT ON DELETE RESTRICT ở cả 3 FK là wording đủ mạnh cho mục tiêu audit-preservation. Điểm tốt là patch v3 đã viết rõ lý do: code được viện dẫn trong lịch sử, không được cascade rename hồi tố.

Minor inline: thêm 1 câu cứng hơn:

“Muốn đổi tên code type = tạo code mới, deprecate/retire code cũ; CẤM UPDATE trực tiếp PK code đang được APR lịch sử tham chiếu.”

Như vậy triết lý sẽ không bị hiểu lỏng thành “RESTRICT chỉ là kỹ thuật, còn ai đó vẫn có thể ALTER tay sau”.

3.2 P13 admin_fallback_log

Kết luận: TỐT, nhưng chưa chặt tối đa.

Schema hiện tại:

  • dot_code, reason, backup_path, patch_diff, verify_evidence, approved_by, retroactive_apr_id, created_at
  • đủ để không còn là text-only fallback.

Rủi ro còn lại:

  • retroactive_apr_id NULL trong một khoảng thời gian là chấp nhận được, nhưng nếu không có SLA/guard thì có cửa “log xong để đấy”, audit bị treo.
  • Chưa có khóa chống duplicate fallback cho cùng 1 dot/session.

Minor inline đề xuất:

  1. thêm status TEXT NOT NULL CHECK (status IN ('applied','retro_apr_pending','closed')) DEFAULT 'retro_apr_pending'
  2. thêm session_code TEXT NOT NULL
  3. thêm partial index hoặc unique guard kiểu:
    CREATE UNIQUE INDEX uq_admin_fallback_open_sessionON admin_fallback_log(dot_code, session_code)WHERE status IN ('applied','retro_apr_pending');
    
  4. thêm rule vận hành: retroactive APR phải được tạo trong 24h, quá hạn → system_issues critical.

=> Không có blocker; chỉ cần khóa vòng đời để không trống cửa audit.

3.3 P14 apr_approvals + trigger quorum

Kết luận: ĐÚNG HƯỚNG, nhưng trigger hiện nên khóa thêm 3 edge case.

Patch hiện cover tốt:

  • high: ≥1 president + ≥2 ai approve, 0 reject
  • medium: ≥1 president approve
  • low: ≥1 approve bất kỳ / auto-rule
  • UNIQUE (apr_id, approver) ngăn double-vote cùng một approver

3 edge case cần khóa thêm:

  1. partial approve race: 2 AI approve xong, chưa có president, có người update status='approved' đồng thời. Trigger sẽ chặn nếu đếm tại thời điểm đó, nhưng nên ghi rõ trigger chạy BEFORE UPDATE OF status và đọc cùng transaction snapshot.
  2. self-approve by proposer/executor: nếu approval_requests.source hay proposed_by trùng approver, hiện schema không chặn. Nên cấm người/agent tạo request tự duyệt request high-risk của chính mình, trừ auto-rule low-risk.
  3. mixed decision stale: một row reject tồn tại rồi sau đó người khác thêm đủ approve. Trigger đã nói “0 reject”, tốt; nhưng nên nói rõ mọi reject mở phải được resolve bằng trạng thái request mới hoặc reopen cycle mới, không được “approve đè lên reject”.

Minor inline đề xuất:

  • Trigger wording:

    BEFORE UPDATE OF status ON approval_requests FOR EACH ROW

  • Thêm constraint/rule:

    “approver không được trùng proposer đối với high-risk action”

  • Nếu có cột proposer chưa tồn tại, ít nhất thêm check ở trigger qua source/metadata hiện có.

3.4 P15 system_issues ALTER

Kết luận: IDPOTENT ĐỦ CHO REPLAY.

ADD COLUMN IF NOT EXISTS + CREATE INDEX IF NOT EXISTS là đúng pattern replay-safe.

Minor inline:

  • index idx_system_issues_coalesce ON (coalesce_key, status) dùng được, nhưng nếu mục tiêu chính là open issues thì partial index sẽ gọn hơn:
    CREATE INDEX IF NOT EXISTS idx_system_issues_coalesce_openON system_issues(coalesce_key)WHERE status='open';
    

Không bắt buộc; hiện tại chưa phải blocker.

3.5 P12 dual-write bridge — chọn option nào cho production?

Kết luận: CHỌN app_lock vài phút, KHÔNG chọn dual-write 24h.

Lý do:

  • Đây là migration governance nhỏ, không phải customer-facing high-throughput lane.
  • dual-write 24h kéo dài complexity window, tăng nguy cơ drift giữa 2 representation và làm troubleshooting khó hơn.
  • app_lock vài phút với pre-announced maintenance gate, backfill, verify, deploy bridge/runtime mới rồi mở lại là sạch nhất, đúng NT9 hơn.

Khi nào mới chọn dual-write 24h?

  • chỉ khi approval_requests là lane cực bận, không thể dừng vài phút, và đã có test coverage mạnh cho cả old/new write path. Hiện bối cảnh gói này không cho thấy cần mức đó.

Minor inline đề xuất:

  • Chốt cứng trong patch:

    “Production mặc định dùng app_lock maintenance gate trong vài phút. Dual-write 24h chỉ là phương án fallback nếu Chủ tịch xác nhận không thể đóng write window.”

3.6 §VIII verify query — đã đủ cover chưa? Có cần version_verified_at?

Kết luận: QUERY ĐỦ CƠ BẢN, nhưng NÊN có dấu audit riêng.

Query hiện kiểm:

  • code
  • version
  • status
  • content_hash
  • enacted_at

Như vậy đủ để chặn drift base law trước enact.

Nhưng nên thêm audit marker, vì nếu không sẽ chỉ là thao tác kiểm tại runtime, khó truy ngược “ai đã verify, khi nào, trước phiên enact nào”.

Khuyến nghị:

  • Không cần đẻ bảng mới.
  • Ghi vào approval_requests.current_state hoặc admin_fallback_log.verify_evidence là sai scope.
  • Cách gọn nhất: thêm 2 cột vào record enact của gói amend trong normative flow hoặc deployment log tương ứng:
    • version_verified_at TIMESTAMPTZ
    • version_verify_snapshot JSONB

Nếu không muốn amend schema ngay, tối thiểu phải chuẩn hóa JSON evidence trong log enact.

3.7 P16 amend_law RESERVED — cơ chế chặn nằm ở đâu?

Kết luận: HIỆN NGHIÊNG VỀ TEXT POLICY + ENGINE GATE; CHƯA DB-FIRST HOÀN TOÀN.

Patch v3 ghi:

  • status='active'
  • handler_ref='unimplemented'
  • dot-apr-execute sẽ chặn

Điều này tốt hơn không chặn, nhưng nút chặn chính vẫn ở engine bash/runtime, chưa phải ở gốc DB. Nếu ai bypass engine hoặc có path khác set status/applied, DB không tự biết handler_ref='unimplemented' là forbidden.

Minor inline rất nên thêm:

  1. đổi triết lý từ status='active' sang status='reserved' nếu sẵn sàng mở rộng enum, hoặc
  2. giữ enum cũ nhưng thêm trigger DB:
    CREATE FUNCTION fn_apr_block_unimplemented_handler() RETURNS TRIGGER AS $$BEGIN  IF NEW.status='approved' AND EXISTS (    SELECT 1    FROM apr_action_types a    WHERE a.action_code = NEW.proposed_action_code      AND a.handler_ref = 'unimplemented'  ) THEN    RAISE EXCEPTION 'APR action % has unimplemented handler_ref', NEW.proposed_action_code;  END IF;  RETURN NEW;END;$$ LANGUAGE plpgsql;
    
  3. áp trigger ở approval_requests khi update status sang approved hoặc applied.

=> Đây là minor quan trọng nhất còn lại. Không cần Round 4, nhưng nên apply inline trước FINAL.

4. Quyết định cuối + lý do

Phán quyết: APPROVE WITH MINOR

Lý do:

  • v3 đã đạt mức sign-off kỹ thuật ở đa số điểm khó nhất.
  • Không còn blocker kiến trúc lớn.
  • Các điểm còn lại đều là minor inline hardening, không cần mở Round 4.

5. Minor patches đề xuất apply inline ngay

M1 — Siết admin_fallback_log

  • thêm status
  • thêm session_code
  • thêm guard/SLA cho retroactive_apr_id

M2 — Hardening trigger quorum

  • ghi rõ BEFORE UPDATE OF status
  • cấm self-approve cho high-risk
  • làm rõ reject không được approve đè

M3 — Chốt production option cho bridge

  • mặc định app_lock vài phút
  • dual-write 24h chỉ là fallback có phê duyệt riêng

M4 — DB gate cho amend_law

  • thêm trigger chặn handler_ref='unimplemented'
  • hoặc mở enum reserved nếu muốn làm sạch semantics hơn

M5 — Audit dấu thời gian verify base version

  • thêm version_verified_at
  • hoặc JSON evidence chuẩn trong log enact tương ứng

6. Kết luận ngắn

Sau khi apply M1–M5 inline, tôi sẵn sàng coi gói v3 là APPROVE FINAL / SIGN-OFF mà không cần Round 4.