All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m48s
- 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>
90 lines
6.9 KiB
Markdown
90 lines
6.9 KiB
Markdown
# 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*.
|