# sub-task-0 — LANE-B REMAINDER (S136 recovery /tiep)

> Vai: implementer (Write/Edit tool). Task: append 2 detector H25 vao scripts/governance-detectors.ps1 + fault-inject 9 ca + real-repo run + AC-B(4)(5)(6).
> Ghi-dia-trong-luc-lam (anti-#53). Cap nhat tung buoc.

## 0. Trang-thai vao (lead da verify — KHONG dung lai)
- `scripts/nhip-no-probe.ps1` DA LAND + verified AC-B(1)(2)(3-logic)(6). KHONG sua tru ca fault-inject CONFIG-THIEU lo bug that.
- `scripts/governance-detectors.ps1` grep 'H25' = 0 → 2 detector CHUA co. Day la viec cua toi.

## 1. Ground-truth (do tu dia truoc khi code)

### 1a. Closeout commits (regex `^\[CLAUDE\] Docs: S\d+.*(closeout|session-end)`) — newest first
| # | commit | subject | predecessor closeout | window |
|---|--------|---------|----------------------|--------|
| 1 | 99fc373 | S134 closeout | e53a693 | (e53a693 .. 99fc373] = {6664a61, 99fc373} |
| 2 | e53a693 | S133 closeout | 9e874ca | (9e874ca .. e53a693] = {d4fbced + 5 wal:flush + e53a693} |
| 3 | 9e874ca | S132 closeout-tail | 72f68d1 | (72f68d1 .. 9e874ca] = {9e874ca} ONLY (72f68d1 = immediate parent) |

### 1b. Union-window ritual-book check on REAL repo (validated via git BEFORE coding)
| window | STATUS.md | HANDOFF.md | NEW session (--diff-filter=A) | agent-memory/** | verdict |
|--------|-----------|------------|-------------------------------|-----------------|---------|
| W1 S134 | YES | YES | YES (S134 file added) | YES (6 diaries) | PASS |
| W2 S133 | YES | YES | YES (S133 file added) | YES (4 diaries) | PASS |
| W3 S132-tail | YES | **NO** | **NO** (S131-S132 file MODIFIED not added in window) | YES (cicd) | **FLAG x2** |

**W3 root-cause (verified):** `9e874ca` parent = `72f68d1` → window = tail commit ONLY. HANDOFF + NEW-session-file were done in `72f68d1` (the EXCLUDED lower bound = the prior session-end that fully closed S131-S132). Tail is a legitimate supplement (late cicd #397 result) → ritual for the SESSION was completed → **W3 flag = FALSE POSITIVE (tail-adjacency artifact)**.
- Decision: implement LITERAL per-commit per instruction. Report W3 as FP + classify (task: "Neu co FLAG that → phan-loai duong-that/duong-gia, KHONG sua detector cho im"). Surface per-label refinement to lead (canonical spec:90 baseline says "union-per-label"; my relay said per-commit). DO NOT unilaterally redesign (owner owns mechanism; adding same-label-skip specifically to green real-repo = "sua detector cho im" = FORBIDDEN).

### 1c. Roster (14 agents, README excluded) + diary bytes
cicd-monitor 22607 | database-agent 7388 | frontend-designer 21492 | harvest-curator 19282 | implementer-backend 17927 | implementer-frontend 15951 | investigator-api 8510 | investigator-codebase 23420 | lead-omission-auditor 3691 | lead-view-auditor 3332 | office-document 3323 | reviewer 17506 | test-specialist 22140 | tooling-auditor 18051
→ 14/14 diaries byte>0. Expect role-notebook = 0 FLAG on real repo.

### 1d. sub-*.md prefix survey (real runs/) — MAPPED vs UNMAPPED
- MAPPED (roster roles): sub-cicd-monitor-*, sub-implementer-backend-*, sub-implementer-frontend-*, sub-investigator-codebase-*, sub-reviewer-*, sub-test-specialist-* ...
- UNMAPPED (prefix not a roster role): sub-impl-runsreadme, sub-impl-sleepcmd, sub-invest-A/B/C, sub-invest-codebase-A-mapping/..., sub-investigator-2-spec-draft, sub-investigator-codebase-A..E (letter-suffix not numeric), sub-lead-omission (not -auditor), sub-lead-view, sub-review-r1/r2/r3/R2/R3, sub-reviewer-1-verdict/3-verdict, sub-task-*, sub-w1-task-*, sub-w2-task-*, sub-w3-task-* ...
- These UNMAPPED must be LISTED, NOT flagged (S122 measure-content-not-name).

## 2. Detector design (locked)

### H25-closeout-ritual (per-commit, LITERAL)
1. `git -C $RepoRoot log --format='%H|%s'` → filter subjects by `^\[CLAUDE\] Docs: S\d+.*(closeout|session-end)` → ordered list newest-first.
2. Loop i in 0..2 (3 most recent). upper=list[i]. lower=list[i+1] (immediately-preceding closeout).
3. If lower missing (i is last closeout in history) → skip case (iv), print reason, no crash.
4. Union files = `git log --name-only --pretty=format: lower..upper` (any touch).
   NEW-session = `git log --diff-filter=A --name-only --pretty=format: lower..upper -- docs/changelog/sessions/` non-empty.
5. Check 4 books: STATUS.md (union), HANDOFF.md (union), NEW-session (diff-filter=A), agent-memory/** (union). Missing → FLAG MED naming book.

### H25-role-notebook (measure content not name)
1. roster = `.claude/agents/*.md` minus README (14).
2. Scan `runs/*/sub-*.md`. Parse `^sub-(.+)-\d+\.md$` (role+numeric idx) else `^sub-(.+)\.md$`. candidate ∈ roster → MAPPED (role has-run). else → UNMAPPED (collect distinct).
3. has-run(role) = (mapped sub-file exists) OR (diary MEMORY.md exists on disk, any size).
4. FLAG MED if has-run(role) AND NOT (diary exists AND byte>0 via (Get-Item).Length). Name missing vs 0-byte.
5. Print UNMAPPED list (INFORM, no flag).

## 3. AC-B(5) — REAL-REPO RUN (governance-detectors.ps1, no -RepoRoot)
```
H25-closeout-ritual: closeouts found 73 ; scoring 3 most-recent
  [ok] 99fc373 S134: union (e53a693..99fc373] all 4 books      PASS
  [ok] e53a693 S133: union (9e874ca..e53a693] all 4 books      PASS
  [MED] 9e874ca S132: window (72f68d1..9e874ca] missing 2/4 -> HANDOFF, NEW-session   FLAG
H25-role-notebook: roster=14 ; diaries-ok=14 ; flagged=0 ; inert=0   PASS
  UNMAPPED (27, INFORM not flagged): impl-runsreadme, impl-sleepcmd, invest-A/B/C, invest-codebase-*, investigator-2-spec-draft, investigator-codebase-A..E, lead-omission, lead-view, reviewer-1-verdict, reviewer-3-verdict, reviewer-R2/R3, review-r1/r2/r3, task, w1-task, w2-task, w3-task
Summary: 0 self-match (C4 satisfied) ; TOTAL FLAGS 46 (45 pre-existing other-detectors + 1 my closeout-FP)
```
**Classification of the 1 flag beyond "3 PASS" expectation:** W3 S132 = **FALSE POSITIVE** (duong-gia). Root-cause verified 1b/parent-check: `9e874ca` parent = `72f68d1` (immediate) + same session batch (S131-S132) → 1-commit window; HANDOFF + NEW-session were done in `72f68d1` = the EXCLUDED lower-bound (the session-end that fully closed S131-S132). The tail is a legit supplement (late cicd #397). No real ritual drift. NOT silenced (per task: classify, don't hack detector). Surfaced to lead: canonical spec:90 baseline = "union-per-label"; per-label folding of same-batch closes would fold this to PASS. Owner decision (do NOT self-apply — adding same-label-skip to green real-repo = "sua detector cho im" = forbidden).
- role-notebook 14/14 + UNMAPPED = EXACTLY spec-expected. 0 duong-that, 0 duong-gia.

## 4. AC-B(6) — code-mo-i
- pure-ASCII: whole file 60003 bytes, non-ASCII count = **0** → append delta 0 non-ASCII. PASS.
- syntax: `[Parser]::ParseFile` → **0 errors**. PASS.
- exit 0: script ends `exit 0` (unchanged, my detectors are advisory Write-Flag only). PASS.
- 0 self-match: Summary self-match check = 0 (my detectors scan git + filenames + diary-bytes, never add the .ps1 to any MD corpus). PASS.

## 5. AC-B(4) — FAULT-INJECT MATRIX (9 ca, temp git tree via -RepoRoot, S95 proves-teeth)
Orchestrator: scratchpad/fault-inject-h25.ps1 ; tree-root: %TEMP%\h25-fi-20260717-174129 (temp, KHONG dung repo that).
| # | case | setup | expected | RESULT | evidence |
|---|------|-------|----------|--------|----------|
| c-i | closeout fake | S11 closeout touches only foo.txt, window (S10..S11] empty of books | FLAG 4/4 | **PASS** | `MED git:eca9ba2 (S11) missing 4 of 4 books -> STATUS,HANDOFF,NEW-session,agent-memory` |
| c-ii | closeout control | S21 close + wal:flush(diary) + STATUS/HANDOFF/NEW-session | PASS | **PASS** | `[ok] d013bb6 S21: union (19b24d2..d013bb6] has all 4 ritual books` ; 0 gap |
| c-iii | tail union-reach | tail S31 touches STATUS only; HANDOFF+NEW-session done by in-window wal:flush | NO FLAG | **PASS** | `[ok] 3bec765 S31: union (4d2320f..3bec765] has all 4 ritual books` ; 0 gap |
| c-iv | lone closeout | 1 closeout only, no predecessor | skip reason, no crash | **PASS** | `[skip] 2fe1887 S40: no earlier close ... not scored, not flagged` + reached Summary/TOTAL FLAGS |
| r-ii | role control | 14 agents + 14 diaries byte>0 + sub-files | PASS | **PASS** | `roster=14 ; diaries-ok=14 ; flagged=0` |
| r-i | role delete | delete reviewer diary (sub-file kept) | FLAG MISSING | **PASS** | `MED agent-memory/reviewer/MEMORY.md ... diary is MISSING` ; diaries-ok=13 flagged=1 |
| r-iv | role 0-byte | truncate reviewer diary to 0 bytes | FLAG 0-byte | **PASS** | bytes=0 ; `MED ... diary is 0-byte (empty notebook)` ; flagged=1 (anti-Goodhart) |
| r-iii | role alien | add sub-invest-A-0.md + sub-w1-task-0.md | UNMAPPED, no flag | **PASS** | `UNMAPPED (2): invest-A, w1-task` ; flagged=0 (S122) |
| p-1 | probe CONFIG-THIEU | counter.json ok + budget.json missing h24_cadence | CONFIG-THIEU in-line + exit0 | **PASS** | `NHIP-NO: kiem CONFIG-THIEU(h24_cadence) | tran-bo-nho 0 over-cap | run-chua-gom 0` ; exit 0 ; not probe-loi |

**9/9 PASS ; 0 FAIL.** Teeth proven BOTH directions: FLAG-correct (c-i, r-i, r-iv, p-1) + PASS/IM-correct (c-ii, c-iii, c-iv, r-ii, r-iii). Probe CONFIG-THIEU handled the missing-key IN-LINE in ve-1 (not generic probe-loi) → **0 probe bug found → no probe change** (respecting "KHONG sua probe").

## 6. Isolation (B6) + AC-B rollup
- Files I touched (in-repo): `scripts/governance-detectors.ps1` (M, LANE-B code) + this `sub-task-0.md` (?? my sub-file). NOTHING else. (scratchpad fault-inject-h25.ps1 = outside repo.)
- AC-B rollup: (1)(2)(3) = probe, LEAD-verified pre-state (not re-done). (4) fault-inject 9/9 PASS. (5) real-repo: role-notebook 14/14 clean + UNMAPPED-27; closeout 2 PASS + 1 FP (S132 tail, classified duong-gia, NOT silenced, per-label refinement surfaced to owner). (6) exit 0 + pure-ASCII delta 0 + parse 0-err + 0 self-match.

## 7. Progress log
- [x] Read spec Items 4+5 + AC-B + existing 2 scripts.
- [x] Ground-truth git windows + diaries + prefixes.
- [x] Append 2 detectors (H25-closeout-ritual + H25-role-notebook).
- [x] AC-B5 real-repo run (2 PASS + 1 FP closeout ; 14/14 role-notebook).
- [x] AC-B6 pure-ASCII delta(0) + parse(0-err) + exit 0 + 0 self-match.
- [x] AC-B4 fault-inject 9/9 PASS on temp tree.
- [x] Isolation verified (2 in-repo files only).
