Files
solution-erp/.claude/workflows/runs/2026-07-24-S149-hoi-tu-bookend/sub-impl-M1-scaffold.md
pqhuy1987 398d343403
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m48s
[CLAUDE] Docs: S149-S150 closeout — bookend lượt đầu end-to-end (hình B) + 2 arc đóng + tally #53 chốt 45
- Arc-1 hội-tụ-bookend (rename 5 vai + 4 máy PS1 + C9-C12) + arc-2 adap-backlog 23/23 + probe Opus-5 khép (S149)
- Bookend @close S150: wave 6 vai (4 đo + 2 KIỂM) → 20 FLAG disposition từng-dòng; ring1 31/34-ĐẠT, ring2 10/10 + M-1 view-stale-role-desc
- Khoá _frozen_until_owner CẮM trước h24-signal-write (frozen-held in thật); 9 class FIRE; JUMP dải {5,4,4,3}+asym{1,4} chờ anh #21
- STATUS bump CURRENT S149-S150 + 2 khối Recently Done; HANDOFF segment mới + re-stamp đủ-slug + (17)(18)(19) lật + (14) viết lại + 6 slot #21-#26
- K2 posture-A @engine PHẦN K + K5 luật TÁCH vòng-đo-mới @session-end (O-2/O-3 OWNER-DELEGATED execute)
- sleep-doc derive-monitor-set (bỏ hardcode 4-tên); spawn-model-audit desc/comment fix; h24-signal-write param-default fix (first-live bug)
- M9 on-behalf ×3 (tooling + inv-cb F3 + reviewer F4); ring1/ring4 nhà seed; ring2 3 cite-dead vá
- Sổ garble #53 derive-from-body chốt 45 + sub-class ngược-#53/skeleton-ruột-rỗng (ghi-đĩa CẦN-KHÔNG-ĐỦ)
- Session-log S149-S150 (Sàn-5 đăng-ký 6 run=) + closeout-synthesis dạng-1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:17:05 +07:00

90 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# sub-impl-M1-scaffold — S149 hoi-tu bookend (implementer/hmw)
> Vai: **implementer (hmw)** · Deliverable: **M1** (checklist **K1**).
> Con-trỏ spec: `spec-hoi-tu-bookend-24-07-2026.md` §② M1 (dòng 32-33) + §③ K1 (dòng 72).
> Khung hub tham chiếu (TAILOR, không copy): `AI_INFRA/scripts/session_scaffold.py` (169 dòng) + `AI_INFRA/.claude/templates/session-context-template.md`.
> Status: **DONE — 4/4 K1 PASS + 6/6 boundary PASS.**
---
## 0. Phạm-vi + 2 deliverable
1. `scripts/session-scaffold.ps1` — 2 mode `-New` / `-Ensure` (**FILE MỚI**).
2. `.claude/templates/session-context-template.md` — template tách file. **ĐÃ tồn tại** dạng draft (generator=`session_scaffold.py`, placeholder `{{TS_SOURCE}}`) → **reconcile 2 sửa surgical** về `session-scaffold.ps1` + `{{HEAD}}`.
ISOLATION: chỉ đụng 2 file trên + sub-MD này. Git-status xác nhận footprint = đúng 3 file (mọi thay-đổi khác trong tree là của em-main/sub song song M2-M5, KHÔNG phải tôi).
---
## 1. Quyết-định thiết-kế
**D1 — 2 mode tách-đôi (khớp S146):**
- `-New`: cấp session MỚI = `max+1` (session-start ONLY). `-N <k>` tùy chọn pin id tường minh; nếu `session-<k>` đã tồn tại (folder HOẶC `_context`) → **COLLISION exit 4, ghi KHÔNG gì**.
- `-Ensure`: heal idempotent session HIỆN TẠI (pause/tiep). `_context` thiếu → tạo; `_context` có → **exit 0 NO-OP** (mtime giữ nguyên). `-N` tùy chọn; mặc định = `max`.
- Phát hiện `-N` tường-minh qua `$PSBoundParameters.ContainsKey('N')` (không dùng sentinel bẩn).
**D2 — ts-mốc = git-committer, CẤM wall-clock (spec M1:33):** `git -C <RepoRoot> log -1 --format=%cI` cho ts + `--format=%h` cho HEAD-sha. Chạy qua helper `Invoke-Git` (EAP=Continue cục bộ → cây-non-git exit 128 KHÔNG throw dưới `$ErrorActionPreference='Stop'` toàn cục).
- 🔸 **DEVIATION-vs-hub tường minh:** hub `head_ts()` (py :49-71) fallback `datetime.now(UTC)` gắn tag `FALLBACK`. SE **từ chối fallback** → git-down = **exit 3**. Lý do: ts nuôi phép đo **C10 LATENESS** (so ts-scaffold vs ts-đầu-phiên) — wall-clock phá tính-xác-định. Chứng răng ở BC6.
**D3 — CẤM đè `_context` (mọi mode):** hard-guard trong `Write-Context``Test-Path` trước khi ghi, tồn-tại → `Fail exit 5`. Backstop độc-lập với logic mode (New chặn @collision, Ensure chặn @no-op); guard là tầng phòng-thủ cuối.
**D4 — encoding:** đọc template `[IO.File]::ReadAllText(path, UTF8)` (decoder .NET tự strip BOM), render bằng `String.Replace` literal (KHÔNG regex → `<N>`/`<k>` trong ENTRY-SCHEMA sống sót, khớp lý-do hub py:74-76), ghi `[IO.File]::WriteAllText` + `UTF8Encoding($false)` no-BOM + normalize CRLF→LF. Render thay đúng 3 placeholder: `{{N}}` `{{TS}}` `{{HEAD}}`.
**D5 — pure-ASCII code (gotcha #30/#37):** `.ps1` = 6785 byte, 0 byte>127, no-BOM (đo byte-level). Tiếng Việt CHỈ nằm trong template `.md` (render đúng, chứng ở §2). Message trong `.ps1` = English/ASCII.
**D6 — `-RepoRoot` fault-inject seam** (default `$PSScriptRoot\..`, khớp house-style `distill-shard-probe.ps1:13`) → chạy trên cây tạm chứng RĂNG.
**Exit codes:** 0 ok/no-op · 2 usage · 3 git-unavailable · 4 collision · 5 defensive-overwrite-block.
**Template reconcile (2 sửa):**
```
- nguon-ts={{TS_SOURCE}} | generator=scripts/session_scaffold.py
+ nguon-ts=git log -1 --format=%cI @ HEAD {{HEAD}} | generator=scripts/session-scaffold.ps1
```
(+ dòng ts-mốc `(nguồn: {{TS_SOURCE}})``(nguồn: git log -1 --format=%cI @ HEAD {{HEAD}})`). Giữ nguyên toàn-bộ 3-block SE-tailored sẵn có (STOCK-map rows SE: STATUS/HANDOFF/.session-counter/broadcasts).
---
## 2. Fault-inject K1 — 4 ca (chạy THẬT trên cây tạm scratchpad `fi-scaffold`, git-init + commit)
Harness: `scratchpad/fi-run.ps1`. Gọi script qua **child `powershell.exe -File`** (bắt buộc — `exit N` in-process sẽ giết harness; child-process cho `$LASTEXITCODE` thật + test dưới PS 5.1 thật).
| Ca | Kỳ vọng | Kết quả đo | Verdict |
|---|---|---|---|
| (a) `-Ensure` ×2 | lần 2 exit 0 + mtime `_context` KHÔNG đổi | run1.exit=0 (create) · run2.exit=0 · mtime_eq=True · hash_eq=True (sleep 1.2s giữa 2 lần → nếu ghi-đè mtime PHẢI đổi) | **PASS** |
| (b) `-New` khi max=3 | tạo `session-4` | exit=0 · session-4 tạo · noLeftover-`{{`=True · sID=4 · gen=ps1 · ts=git-cI khớp · head=%h khớp · only4=True · noBOM · noCRLF | **PASS** |
| (c) `-New -N 3` collision (folder) | exit≠0 + 0 ghi | exit=4 · `_context-s-3.md` KHÔNG được tạo | **PASS** |
| (d) `_context` tồn tại + `-New -N 3` | exit≠0 KHÔNG đè | seed.exit=0 · collide.exit=4 · hash_eq=True · mtime_eq=True (sleep 1.2s giữa) | **PASS** |
**Evidence render (session-4 `_context`):**
```
# _context-s-4 — SESSION-MODEL narrative durable
<!-- SCAFFOLD-META: sID=4 | ts-moc=2026-07-24T23:56:20+07:00 | nguon-ts=git log -1 --format=%cI @ HEAD 010b4bf | generator=scripts/session-scaffold.ps1 -->
> ts-mốc khởi-tạo = 2026-07-24T23:56:20+07:00 (nguồn: git log -1 ... @ HEAD 010b4bf) — mốc git-committer, KHÔNG phải wall-clock
```
(Tiếng Việt render đúng, no mojibake; ts = committer-ts của HEAD cây-tạm, KHÔNG wall-clock.)
### Boundary checks bổ sung (anti-Goodhart — chứng create-path FIRE, không chỉ refuse):
| BC | Kỳ vọng | Đo |
|---|---|---|
| BC1 `-New` cây FRESH (max=0) | tạo session-1 | exit=0 created=True **PASS** |
| BC2 `-New -Ensure` cùng lúc | usage exit 2 | exit=2 **PASS** |
| BC3 không mode | usage exit 2 | exit=2 **PASS** |
| BC4 `-Ensure` default=max (session có) | no-op exit 0 | exit=0 **PASS** |
| BC5 `-Ensure` cây rỗng (0 session) | exit 2 (không gì để heal) | exit=2 **PASS** |
| BC6 git-unavailable (cây non-git) | exit 3 (từ chối wall-clock) | exit=3 **PASS** |
BC6 = chứng RĂNG của invariant "CẤM wall-clock" (D2); BC1 = chứng script THẬT tạo được (không Goodhart-refuse-all).
---
## 3. Verdict
**M1 DONE — 4/4 K1 PASS + 6/6 boundary PASS.** 2 deliverable:
- `scripts/session-scaffold.ps1` (mới, pure-ASCII, PS 5.1 parse-clean)
- `.claude/templates/session-context-template.md` (2 sửa surgical → ps1-generator + `{{HEAD}}`)
**CÒN LẠI cho em-main (NGOÀI write-scope của tôi — isolation):**
- 🔴 **K1 "vết-chữ-owner"**: "quyết định owner liên quan phải có ≥1 hit trên bề-mặt bền (MARKS/ledger)". Đây là ghi vào `ACTIVE-MARKS.md`/ledger — **thuộc em-main**, tôi KHÔNG đụng (isolation). Nhãn quyết-định hình-B = `OWNER-DELEGATED → lead-decided` (spec dòng 29). Em-main cần verify ≥1 hit trên MARKS/ledger.
- **Wire call-site**: script chưa được gọi từ `session-start`/`tiep` (đó là **M6/K6 = em-main**, land SAU M4 theo thứ-tự spec dòng 64-65). M1 chỉ giao *bộ máy CLI*.