KB-2713 rev 2

LỆNH 2B — DOT reconcile Balo 4 loại — báo cáo hoàn tất dry-run

9 min read Revision 2
codexreportbalodotdry-runverify2026-07-16

LỆNH 2B — DOT reconcile Balo 4 loại — báo cáo hoàn tất dry-run

Ngày: 2026-07-16
Verdict: READY_FOR_OWNER_APPLY_GATE
Trạng thái production data: CHƯA APPLY; public.balo_thuc_the không đổi
Phạm vi: đúng 4 loại table | view | function | trigger; không cron, không UI, không deploy/restart/reload.

0. Checklist 8 bước

  • Đọc skill Incomex, Operating Rules, Hiến pháp v4.6.3, luật Balo, Điều 33 và Điều 35.
  • Gate 0: schema contract và sequence live PASS.
  • Thiết kế một DOT canonical với ba mode.
  • Tạo bin/dot-balo-reconcile.
  • Tạo SQL atomic và thêm đúng một dòng mission vào manifest trong commit.
  • bash -n, shellcheck, SQL read-only validation PASS.
  • Chạy production --dry-run--verify; fingerprint trước/sau giống hệt.
  • Commit local trong DOT SSOT đúng 3 file; không git add -A.
  • Upload KB và kiểm list → full read → semantic search (evidence ở mục 10).

1. Ba câu tuyên ngôn

  1. Vĩnh viễn: một DOT tính delta từ live pg_catalog mỗi lần chạy, không dùng số/key hiện tại và không vá hai dòng riêng lẻ.
  2. Nhầm được không: schema/sequence/hash/manifest/conflict là hard gate; apply tương lai chỉ qua dot-pg-atomic-apply; KEEP không phát sinh UPDATE.
  3. Tự động: DOT tự phân loại KEEP/ADD/REVIVE/METADATA_UPDATE/MARK_MISSING/CONFLICT cho cả tập 4 loại; cron là quyết định vận hành ngoài mission.

2. File và kiến trúc tối giản

File trong SSOT /opt/incomex/dot:

File Vai trò SHA-256
bin/dot-balo-reconcile Một entrypoint canonical: --dry-run, --apply, --verify 7e657b96cc27e0f396e2485a67d6296c4de10aabd2f68cf4aaf367cb7b9bdfe5
sql/balo-reconcile.sql Plan/apply atomic; apply mặc định chỉ khi gateway gọi c018f12ce86918c2a6199b70c4626c981deb2632edc686c1544504a3cf387369
sql/approved-sql-manifest.tsv Thêm đúng một hash-lock cho balo-reconcile.sql trong commit mission working SHA có cả thay đổi có sẵn: fb86bee730f76464c385f3da7be65ad81fc5a718f25b84a554404a13dde070fd

Kiến trúc:

  • --dry-run--verify ép default_transaction_read_only=onbalo.reconcile_apply=off trước transaction.
  • --apply tồn tại cho gate sau, nhưng không chạy trong mission này. Đường duy nhất là /opt/incomex/dot/bin/dot-pg-atomic-apply /opt/incomex/dot/sql/balo-reconcile.sql.
  • SQL tự gate trước WRITE và kiểm delta bằng 0 trong cùng transaction trước COMMIT; lỗi thì atomic gateway rollback.
  • Không tạo verifier/framework/registry/daemon mới; verifier nằm trong cùng DOT.

3. Gate schema live — PASS

Output thật:

attname      attgenerated  expression
stt                       nextval('balo_stt_seq'::regclass)
da_mat                   false
loai_census s             split_part(khoa_nhan_dien, ':'::text, 1)
date_created             now()
date_updated             now()

census_kinds={function,table,trigger,view}
rows=2146 distinct_stt=2146 distinct_keys=2146 max_stt=2146

Kết luận contract:

  • stt dùng DEFAULT sequence; ADD không truyền stt.
  • loai_census là STORED GENERATED từ khoa_nhan_dien; SQL không INSERT/UPDATE cột này.
  • da_mat=false, date_created=now(), date_updated=now() là default live.
  • loai là trục nhãn thủ công, không xuất hiện trong danh sách cột ghi.

4. Sequence/duplicate/conflict — PASS

Output thật:

schema_issues|max_stt|last_value|is_called|increment_by|predicted_next_value|sequence_safe|stt_dup|key_dup|catalog_key_duplicates|unexpected_kind
0|2146|2146|t|1|2147|t|0|0|0|0

scope|identifier|reason
(0 rows)

Không gọi nextval, setval hay sửa sequence trong dry-run/verify. Nếu sequence mất an toàn, DOT trả HOLD: SEQUENCE_REPAIR_REQUIRED; sửa sequence phải là gate riêng.

5. Dry-run production thật

SQL_LOCK|manifest=PASS|sha256=c018f12ce86918c2a6199b70c4626c981deb2632edc686c1544504a3cf387369|atomic_guard=PASS_NONEXECUTING
kind|catalog|keep|add|revive|metadata_update|mark_missing|conflict
table|385|383|2|0|0|0|0
view|699|699|0|0|0|0|0
function|654|654|0|0|0|0|0
trigger|410|410|0|0|0|0|0
TOTAL|2148|2146|2|0|0|0|0

ADD|table:public.sua_re_khai_niem_nhap|||{"ten": "sua_re_khai_niem_nhap", "noi_luu": "public"}|catalog key has never had a Balo row
ADD|table:public.sua_re_ui_khai_niem_nhap|||{"ten": "sua_re_ui_khai_niem_nhap", "noi_luu": "public"}|catalog key has never had a Balo row

BALO_RESULT|add=2|revive=0|metadata_update=0|mark_missing=0|conflict=0|sequence_safe=t
FINGERPRINT|before=2146|1|2146|7ab8e6ffc18705ce6a35da1bb89d4df4|2146|t|1
FINGERPRINT|after=2146|1|2146|7ab8e6ffc18705ce6a35da1bb89d4df4|2146|t|1
FINGERPRINT|unchanged=PASS
DRY_RUN|PASS|delta=2|write=0

Hai khóa chỉ xuất hiện trong output do live catalog sinh ra. Scan code không tìm thấy các số 2146/2147 hay hai key hiện tại.

6. Verify production thật

BALO_RESULT|add=2|revive=0|metadata_update=0|mark_missing=0|conflict=0|sequence_safe=t
FINGERPRINT|before=2146|1|2146|7ab8e6ffc18705ce6a35da1bb89d4df4|2146|t|1
FINGERPRINT|after=2146|1|2146|7ab8e6ffc18705ce6a35da1bb89d4df4|2146|t|1
FINGERPRINT|unchanged=PASS
VERIFY|READY_TO_APPLY|delta=2|write=0

Đây là trạng thái sẵn sàng xin Owner gate, không phải đã reconcile. Sau apply ở mission khác, cùng --verify chỉ trả PASS_RECONCILED khi toàn bộ delta bằng 0.

7. Chứng minh rào chắn dữ liệu

  • ADD duy nhất là INSERT INTO public.balo_thuc_the (ten, noi_luu, khoa_nhan_dien); sequence/generated/default tự xử lý các cột còn lại.
  • UPDATE chỉ có hai nhánh: cùng key thì cập nhật ten/noi_luu/da_mat/date_updated; mất khỏi catalog thì chỉ da_mat/date_updated.
  • KEEP không đi vào UPDATE, nên giữ nguyên dữ liệu và date_updated.
  • Không ghi nhom, loai, chuyen_mon, lop, ghi_chu, kiem_soat, active, stt, loai_census.
  • METADATA_UPDATE chỉ áp dụng cùng khoa_nhan_dien; rename/chuyển schema tự nhiên thành khóa mới ADD và khóa cũ MARK_MISSING, không ghép identity.
  • Bộ lọc/catalog và key được dựng mỗi lần chạy từ PG: relkind='r', relkind='v', prokind='f', NOT tgisinternal; loại pg_catalog, information_schema, pg_toast%.
  • Gateway thật đã kiểm allowlist/hash/static rồi bị dừng có chủ ý tại tên container không tồn tại: atomic_guard=PASS_NONEXECUTING; vì vậy validation gateway không thể chạy SQL.

8. Hai mũ và kiểm tra mã

Mũ triển khai: xây một entrypoint/SQL/manifest, chạy SQL thật dưới role production nhưng ép transaction read-only.

Mũ hoài nghi: kiểm riêng hash-lock, static atomic guard, conflict diagnostics, fingerprint toàn bảng + sequence, scope commit và thời điểm container.

Output thật:

BASH_N=PASS
SHELLCHECK=PASS
274: INSERT INTO public.balo_thuc_the (ten, noi_luu, khoa_nhan_dien)
291: UPDATE public.balo_thuc_the b
310: UPDATE public.balo_thuc_the b
HARDCODE_SCAN=PASS

PostgreSQL container vẫn có StartedAt=2026-04-17T05:35:18.48439927Z; mission không restart/recreate. Không có deploy, reload, scheduler hay UI change.

9. Git scope

Commit local DOT SSOT:

65a2d732dd31459ce9d9312fce5b36c9ac9627a3
feat(balo): add four-kind reconcile dry-run gate

bin/dot-balo-reconcile
sql/approved-sql-manifest.tsv
sql/balo-reconcile.sql

Commit manifest chỉ thêm một dòng mission. Sáu dòng sql/sua-re/* đã tồn tại trong working tree trước mission và được giữ nguyên, không bị đưa lẫn vào commit. Không dùng git add -A.

10. Evidence và KB

  • VPS: /opt/incomex/evidence/balo-reconcile-2b-20260716/
  • Workspace: knowledge/current-state/reports/evidence/balo-reconcile-2b-20260716/
  • Báo cáo KB: knowledge/current-state/reports/codex-lenh-2b-balo-reconcile-dryrun-2026-07-16.md
  • File chính: gate0.log, dry-run.log, verify.log, static-checks.log, commit-diff.patch, preinstall-state.log, post-state.log.

Xác minh KB thật sau upload:

LIST: count=1, revision=1, đúng document_id nêu trên
FULL READ: truncated=false, content_length=8194, mở đầu đúng verdict READY_FOR_OWNER_APPLY_GATE
SEMANTIC SEARCH: kết quả hạng 1 là chính báo cáo này, score=0.9053328;
snippet chứa commit 65a2d732... và đúng ba file mission

Sau khi ghi evidence xác minh này, tài liệu được update thành revision 2 và đọc lại để bảo đảm nội dung cuối vẫn đầy đủ.

11. Kết luận và Owner gate

READY_FOR_OWNER_APPLY_GATE. DOT tái sử dụng cho hiện tại và object tương lai đã sẵn sàng; live đang còn đúng 2 ADD, conflict=0, sequence safe, SQL/manifest/hash hợp lệ và dry-run/verify không đổi một byte Balo.

DỪNG tại đây. Không chạy dot-balo-reconcile --apply cho tới khi Owner ra gate riêng.