KB-3CAF

Dieu43 Block 1 Phase 2 APPLY Report S178 Fix 11

8 min read Revision 1
dieu43phase2applyreports178-fix11filesystem-init

Đ43 Block 1 Phase 2 APPLY — Report

Ngày chạy: 2026-04-17 06:38-06:42 UTC+7 Phiên: S178 Fix 11 Agent: Claude CLI (claude-go) qua SSH alias contabo VPS: vmi3080463 (38.242.240.89)

CHECKPOINT

Đã đọc: Đ43 §6+§7+§8, phụ lục Đ43 §3.2+§5, Đ33 §13+§15, Đ41 VPS-SSOT, Đ35 v5.1 §3+§8.

QUYẾT ĐỊNH THIẾT KẾ

1. Cấu trúc folder — chọn Interp B (siblings, theo luật gốc §6+§11)

Folder Rationale
/opt/incomex/context-pack/ Main — chứa build_id dirs + symlinks current/previous (symlinks được tạo ở Phase 8, không phải Phase 2)
/opt/incomex/context-pack.tmp/ SIBLING dot-prefix, per §6 Bước 5 explicit path /opt/incomex/context-pack.tmp/<build_id>/
/opt/incomex/context-pack-staging/ SIBLING dash-prefix, per §11 Bước 7 "+.tmp/, -staging/, previous/" — phân biệt -staging/ với .tmp/ qua prefix symbol

Lý do chọn Interp B (thay vì 4-subdir của phụ lục §3.2):

  • Luật gốc §6 Bước 5 rõ ràng: path temp là /opt/incomex/context-pack.tmp/... (sibling, dot-prefix). Nếu .tmp là subdir thì path sẽ là /opt/incomex/context-pack/.tmp/...
  • §11 Bước 7 (authoritative) dùng dấu + và prefix symbol để gợi ý cấu trúc sibling
  • Phụ lục §3.2 ("4 folder: current/, .tmp/, -staging/, previous/") được soạn sau, và -staging/ làm tên folder thực tế rất bất thường (dash leading)
  • HP v4.6.1 NT9 "luật gốc > phụ lục" khi mâu thuẫn
  • current/previous/ KHÔNG phải folder — là SYMLINKS tạo ở Phase 8 (§7c "Symlink swap current -> <build_id>")

2. Ownership — dùng chown --reference=/opt/incomex/dot/bin/ thay vì hardcode incomex:incomex

Lý do: OS user incomex KHÔNG tồn tại trên VPS hiện tại (id incomex → no such user). /opt/incomex/dot/bin/ de facto owned bởi UID:GID 1001:1001 (unnamed). Script dùng --reference để kế thừa ownership:

  • Tránh hardcode user không tồn tại (script sẽ fail ở runtime)
  • Khi Desktop sau này quyết định tạo user incomex:incomex với UID 1001 → chown existing dirs → script tự động follow mà không cần sửa code

Cần Desktop quyết: Có tạo OS user incomex:incomex (UID/GID 1001) trên VPS hay giữ pattern unnamed 1001:1001 hiện tại? Phạm vi quyết định rộng hơn Phase 2, affects toàn bộ /opt/incomex/.

VỊ TRÍ FILE

Script Path Bytes SHA256
dot-dieu43-fs-init.sh /opt/incomex/dot/bin/dot-dieu43-fs-init.sh 4966 57fcab23777630351e1c2eeb0236413258b4d5afe5a3394d46b0a969a8e7ff4a
dot-dieu43-fs-verify.sh /opt/incomex/dot/bin/dot-dieu43-fs-verify.sh 3853 506dc7e26b0504824305030258bebce403f49c7a83e1d8a39eadaeeec35bfdbe

Cả 2 file soạn thẳng trên VPS qua SSH heredoc (Đ41 NT: không scp về local, không qua CI/CD).

10 TIÊU CHÍ C1-C10

C1 — 2 script tồn tại + exec permission → PASS

-rwxr-xr-x 1 root root 4966 Apr 17 06:37 dot-dieu43-fs-init.sh
-rwxr-xr-x 1 root root 3853 Apr 17 06:38 dot-dieu43-fs-verify.sh

C2 — syntax OK → PASS

$ bash -n dot-dieu43-fs-init.sh && echo OK   → OK
$ bash -n dot-dieu43-fs-verify.sh && echo OK → OK

C3 — shebang + usage + exit codes → PASS

  • Shebang: #!/usr/bin/env bash (cả 2)
  • set -euo pipefail (cả 2, per Đ33 §13 DOT template)
  • Usage: --help|-h print hướng dẫn + exit 0
  • Unknown option → exit 2 (USAGE)
  • Exit codes: 0=OK/PASS, 1=ERROR/FAIL, 2=USAGE (mở rộng từ template Đ33 0/1 — 2 cho USAGE là convention bash chuẩn)
  • Log prefix theo pattern dot-permission-ensure: [INFO], [OK], [SKIP], [ERR], [PASS], [FAIL]
  • init idempotent-by-design (skip nếu folder OK, fix nếu mode lệch, tạo nếu thiếu)
  • verify = read-only (no chmod/chown/mkdir)

C4 — folder FS đầy đủ theo §6 Đ43 → PASS

3 folder tồn tại sau init run 1:

/opt/incomex/context-pack             d owner=1001:1001 mode=755
/opt/incomex/context-pack.tmp         d owner=1001:1001 mode=755
/opt/incomex/context-pack-staging     d owner=1001:1001 mode=755

C5 — owner + mode đúng → PASS

Reference /opt/incomex/dot/bin/ = owner=1001:1001 mode=755. Cả 3 folder match exact.

C6 — init run 1: exit 0 + folders created → PASS

$ /opt/incomex/dot/bin/dot-dieu43-fs-init.sh
[OK] /opt/incomex/context-pack (created)
[OK] /opt/incomex/context-pack.tmp (created)
[OK] /opt/incomex/context-pack-staging (created)
Summary: created=3 fixed=0 skipped=0
EXIT=0

C7 — init run 2: idempotent exit 0 + 0 thay đổi → PASS

$ /opt/incomex/dot/bin/dot-dieu43-fs-init.sh   # run 2
[SKIP] /opt/incomex/context-pack
[SKIP] /opt/incomex/context-pack.tmp
[SKIP] /opt/incomex/context-pack-staging
Summary: created=0 fixed=0 skipped=3
EXIT=0

Diff stat (before vs after run 2): 0 diff (owner + mode không đổi).

C8 — verify normal: exit 0 → PASS

$ /opt/incomex/dot/bin/dot-dieu43-fs-verify.sh
[PASS] /opt/incomex/context-pack (owner=1001:1001 mode=755)
[PASS] /opt/incomex/context-pack.tmp (owner=1001:1001 mode=755)
[PASS] /opt/incomex/context-pack-staging (owner=1001:1001 mode=755)
Summary: pass=3 fail=0
EXIT=0

C9 — verify BẮT lỗi khi cố tình sai permission → PASS

$ chmod 700 /opt/incomex/context-pack.tmp
$ /opt/incomex/dot/bin/dot-dieu43-fs-verify.sh
[PASS] /opt/incomex/context-pack (owner=1001:1001 mode=755)
[FAIL] /opt/incomex/context-pack.tmp — mode mismatch (got 700, expected 755)
[PASS] /opt/incomex/context-pack-staging (owner=1001:1001 mode=755)
Summary: pass=2 fail=1
[FAIL] Phase 2 filesystem NOT OK — 1 issue(s):
[FAIL]   - /opt/incomex/context-pack.tmp: mode=700 != 755
[FAIL] Repair: rerun /opt/incomex/dot/bin/dot-dieu43-fs-init.sh
EXIT=1

Sau đó init repair → verify exit 0 lại.

C10 — paired_dot cross-reference trong header → PASS

  • dot-dieu43-fs-init.sh header line 23: # PAIRED DOT: dot-dieu43-fs-verify (Tier A, /opt/incomex/dot/bin/dot-dieu43-fs-verify.sh)
  • dot-dieu43-fs-init.sh line 30: # paired_dot = DOT-DIEU43-FS-VERIFY
  • dot-dieu43-fs-verify.sh line 18: # PAIRED DOT: dot-dieu43-fs-init (Tier B, /opt/incomex/dot/bin/dot-dieu43-fs-init.sh)
  • dot-dieu43-fs-verify.sh line 25: # paired_dot = DOT-DIEU43-FS-INIT

TỔNG KẾT 10 TIÊU CHÍ: 10/10 PASS

MÂU THUẪN / VẤN ĐỀ CẦN DESKTOP QUYẾT

Issue 1: Cấu trúc folder — mâu thuẫn luật gốc §6/§11 vs phụ lục §3.2

Đã quyết tại CLI: chọn Interp B (3 siblings). Nếu Desktop muốn Interp A (4 subdirs) thì cần amend phụ lục HOẶC init script — flag lại.

Issue 2: OS user incomex:incomex không tồn tại trên VPS

Đã giải quyết tạm: dùng chown --reference=/opt/incomex/dot/bin/ — kế thừa UID:GID 1001:1001 hiện hữu. Không tạo user mới (out of Phase 2 scope). Desktop cần quyết: có tạo OS user incomex với UID/GID 1001 để đặt tên cho pattern hiện tại không? Ảnh hưởng toàn bộ /opt/incomex/ chứ không riêng Đ43.

Issue 3: dot_run_logfn_log_issue chưa tồn tại trong DB

Quan sát: DB directus hiện KHÔNG có bảng dot_run_log hay function fn_log_issue. 2 thành phần này thuộc Đ35 v5.1 BLOCK 4 (chưa enact). Xử lý tại CLI: 2 script Phase 2 chỉ log ra stdout/stderr + exit code — KHÔNG call fn_log_issue(), KHÔNG INSERT vào dot_run_log. Khi Đ35 v5.1 BLOCK 4 enact xong, sẽ retrofit logging vào scripts (scope Phase 5 hoặc task Đ35 riêng).

KẾT LUẬN

Phase 2 PASS. Sẵn sàng Phase 4 (Phase 3 đã xong Desktop-side).

3 folder cơ sở + 2 DOT script (Tier B init + Tier A verify, paired) đã deploy trên VPS theo đúng §6/§11 Đ43 và Đ33 §13.1 E1 (schema bootstrap — register ở Phase 5). Idempotency + sabotage-recovery verified end-to-end.

GHI CHÚ

  • Script sống trên VPS tại /opt/incomex/dot/bin/dot-dieu43-fs-init.sh + dot-dieu43-fs-verify.sh (KHÔNG sync về local, KHÔNG push git — Đ41).
  • 11 fields register (Phase 5) đã ghi trong header comment mỗi script.
  • Rollback nếu cần: rm -rf /opt/incomex/context-pack{,.tmp,-staging} + rm /opt/incomex/dot/bin/dot-dieu43-fs-{init,verify}.sh — chờ Desktop quyết, KHÔNG tự rollback.

Report generated by Claude CLI — S178 Fix 11 — 2026-04-17 Phase 2