[CLAUDE] Docs: adopt Harness-11 engine tự-bảo-trì (3-workflow audit→implement→review)
- engine-doc canonical docs/governance/harness-11-engine.md (PHẦN A/B/C/D + 3-tier D5/D6/D7 + one-direction-lock D8 + CAVEAT honest) - scripts/governance-detectors.ps1 (C1 broken-pointer + C2/B3 staleness + C3 vocab-fork + C4 self-exclusion + C5 resolve, NO-API DÒ+FLAG-only, runtime-proven, FP-refined 59→27) - scripts/memory-archive-gate.ps1 (PHẦN A: hysteresis 0.85 + keep-floor 5 + 2-strike + A7 NO-API L1-eval) + budget.json archive_gate - B1 ×11 count→canonical-pointer (root CLAUDE.md, ef-core/dep-audit SKILL, skills/README, docs/CLAUDE.md) — drift mig53→55/test306→339/gotcha68→69 RESOLVED + ef-core +Mig 54/55 rows - cadence-wire D1 session-start §2.1.3 + D2 session-end §L.b(c) + agents/README Upgrade S75 - run-trace TRACKED: audit wf_7fdc3bd5-930 / implement wf_c5e5844e-7c1 / review wf_d7ca1ff8-942 (REVIEW PASS, completeness-gate ĐẠT) - check-email AI_INFRA harness-11 (verify whole-file 318ff9f6 + body b2a2fc1c) + adap-report + outbox report (body 7fa1b53a) - 0 production code; state THẬT giữ nguyên (Mig 55 · 88 bảng · 339 test · gotcha 69 · menu 54 · bundle BYF5vIMJ/CB-tiRxd) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,42 @@
|
||||
# IMPLEMENT SYNTHESIS — Harness-11 adap (2026-06-18-h11-implement · `wf_c5e5844e-7c1`)
|
||||
|
||||
> 2× general-purpose (script, file-disjoint ∥) + em-main single-writer (governance MD cluster). Em-main scribe synthesis @P3.
|
||||
|
||||
## Sub Lane 1 — `scripts/governance-detectors.ps1` (PHẦN C + B3) ✅ RUNTIME-PROVEN
|
||||
- 401 dòng, ASCII-only body, PS 5.1, exit 0. Flag: **71 pre-B1 → 59 post-B1 → 27 post-refinement (R2)** (HIGH=0) — drift-fix + FP-cut (C2 context-skip table-row/version/historical + C1 `[-_]` normalize), C4 0 self-match suốt.
|
||||
- **C1 broken-pointer:** gotcha-ref 0 dangling (sạch) + **29 dangling-wikilink** (hyphen-form `[[feedback-x]]` vs file underscore `feedback_x.md` — REAL inconsistency, để REVIEW judge FP-vs-real).
|
||||
- **C2/B3 staleness:** bắt đúng drift root CLAUDE.md (mig53→55·test306→339·gotcha68→69) = runtime proof. Canonical đọc STATUS.md + cross-check disk (mig=55, gotcha=69 khớp → 0 'canonical-stale').
|
||||
- **C3 vocab-fork:** `wave-folder=15f vs run-trace=18f` + bonus `two-tier=17f vs all-inherit=10f` + `Dự trù PRO=7f vs Ngân sách PRO=6f` (rename S65 còn 2 tên sống).
|
||||
- **C4 self-exclusion:** 5 paths excluded, 0 self-match ✓.
|
||||
- **C5 resolve-condition:** 100% FLAG có `resolve:`.
|
||||
- **NO-API verified:** 0 hit Invoke-WebRequest/HttpClient/System.Net/6333/store_memory. Detector **0 auto-write** (Set-Content/Out-File = 0) → DÒ+FLAG-only ✓.
|
||||
- **gotcha #30 RUNTIME-CATCH:** vòng-1 chỉ 53 flag — PS5.1 `-File` decode .ps1 UTF-8-no-BOM bằng ANSI-1252 → literal Việt mojibake → MISS 18 flag (gồm '68 bẫy' + vocab-fork Việt). FIX: body ASCII-only + build token Việt từ code-point runtime (`U @(0x62,0x1EAB,0x79)`). **Minh-chứng giá-trị mandate "chạy thật"** (không runtime → over-claim detector hoạt-động khi nó MÙ token Việt).
|
||||
- **HONEST limitation:** C2 count-token = soft-net ~12 TRUE / ~29 false-pos (version "Core 10", per-row "N bảng module", historical "154 test", greedy cross-line). sev LOW khi |lệch|<10. → người xử cờ, KHÔNG auto-fix (đúng D6).
|
||||
|
||||
## Sub Lane 2 — `scripts/memory-archive-gate.ps1` (PHẦN A) ✅ RUNTIME-PROVEN
|
||||
- 289 dòng, exit 0, DRY-RUN default, NO-API, FLAG-only.
|
||||
- budget.json `archive_gate` block ADDITIVE (autoinject_cap 25600 · low_watermark_ratio 0.85 · keep_floor_entries 5 · strike_threshold 2). `measured`/`tiers`/`last_sleep_at` UNTOUCHED.
|
||||
- **A4 hysteresis** proven (cicd after-est ~21180 < low-water 21760, không dừng ở vạch). **A5 keep-floor** proven (inv/reviewer WARN "keep-floor hit (5); cannot auto-drain - SPLIT/condense" — từ-chối vét-sạch khi 5 entry mới-nhất đã > cap). **A6 2-strike** lifecycle proven (-Apply ×2: run1 strike1 WATCH → run2 strike2 PROPOSE). **A7 NO-API gate** 186/186 pointer resolve across 4 sub có archive + byte-sanity.
|
||||
- DRY-RUN flag over-cap đúng: reviewer 38755 · inv-codebase 31502 · cicd 26798.
|
||||
- 3 bug fixed mid-build (honest): PS-5.1 parser cascade (typo `'`→`"`) · gotcha #30 mojibake (ReadAllText UTF8) · legend-line FP (`^\s*>` skip).
|
||||
|
||||
## Em-main cluster (governance MD — single-writer D9, B4 gated) ✅
|
||||
- **Engine-doc** `docs/governance/harness-11-engine.md` — canonical SE: artifact-map + PHẦN A/B/C/D + **3-tier D5(AUTO)/D6(DÒ+FLAG)/D7(owner-approve) nhãn-hoá EXPLICIT** + **one-direction-lock D8 codify** + CAVEAT honest. Doc khác TRỎ về đây (B1 dogfood).
|
||||
- **B1 pointer + drift-fix (11 edit):** root CLAUDE.md ×7 (count→`docs/STATUS.md` pointer) · ef-core SKILL ×6 (incl +Mig 54/55 rows) · skills/README ×2 · dep-audit SKILL ×1 · docs/CLAUDE.md ×2 (93→88 + 58→pointer). **Post-B1 detector re-run: drift THẬT root CLAUDE.md RESOLVED** (3 real flag gone); còn lại = documented FP (version/per-row/historical).
|
||||
- **Cadence-wire:** session-start §2.1.3 (D1 chạy detector @start) + session-end §L.b(c) (D2 archive-gate @end) + agents/README Upgrade S75 — tất cả TRỎ engine-doc.
|
||||
|
||||
## Completeness-gate status (B+C+D function-floor)
|
||||
- **PHẦN B:** B1 ✅ (pointer + drift-fix) · B2 ✅ (readable giữ) · B3 ✅ (detector C2) · B4 ✅ (em-main gated). ĐẠT.
|
||||
- **PHẦN C:** C1 ✅ · C2 ✅ · C3 ✅ · C4 ✅ (0 self-match) · C5 ✅ (resolve-condition). ĐẠT (runtime-proven).
|
||||
- **PHẦN D:** D1 ✅ (wired session-start) · D2 ✅ (wired session-end) · D3-D4 PRESENT (sẵn) · D5/D6/D7 ✅ (3-tier codify engine-doc) · D8 ✅ (one-direction-lock codify) · D9/D10/D11 PRESENT-mạnh (sẵn). ĐẠT.
|
||||
- **PHẦN A (🟡):** A1-A3 sẵn · A4/A5/A6 ✅ (params + gate) · A7 ✅ (NO-API standing-gate). Mechanized-hoá hơn (tailored).
|
||||
|
||||
## Single-writer (D9) respected
|
||||
git status: sub Lane 1 chỉ tạo `governance-detectors.ps1` + sub-task-0.md · Lane 2 chỉ `memory-archive-gate.ps1` + budget.json + sub-task-1.md · em-main = mọi canonical MD. KHÔNG sub đụng canonical/agent-memory/sibling. Containment CLEAN.
|
||||
|
||||
## Cho REVIEW (W3) đánh-giá
|
||||
1. Completeness-gate: B+C+D đủ-trọn? (claim ĐẠT — verify độc-lập).
|
||||
2. Detector quality: FP-rate C2 (~29/71) có chấp-nhận-được không, hay cần refine regex context-aware? (em KHÔNG tự-refine = tránh self-bias).
|
||||
3. C1 wikilink 29 flag: hyphen-vs-underscore = REAL inconsistency hay detector normalization-FP?
|
||||
4. Honesty: nấc executed-file vs runtime đúng chưa, có over-claim không.
|
||||
5. Containment: single-writer giữ, no auto-write-of-law.
|
||||
24
.claude/workflows/runs/2026-06-18-h11-implement/run.md
Normal file
24
.claude/workflows/runs/2026-06-18-h11-implement/run.md
Normal file
@ -0,0 +1,24 @@
|
||||
# RUN — 2026-06-18-h11-implement (Harness-11 adap · STAGE 2 IMPLEMENT)
|
||||
|
||||
> **Harness-10 FLAT run-trace** (TRACKED). Sub ghi `sub-<role>-<i>.md` phẳng. Synthesis → `implement-synthesis.md`.
|
||||
|
||||
- **Workflow:** Harness-11 adap — IMPLEMENT (fill GAP từ audit-synthesis)
|
||||
- **Mode:** hmw RUN-TRACE. 2× general-purpose (script, file-disjoint ∥) + em-main MD cluster (single-writer D9)
|
||||
- **Opened:** 2026-06-18 (S75)
|
||||
- **Input:** `../2026-06-18-h11-audit/audit-synthesis.md` GAP-list
|
||||
|
||||
## Phân-công (single-writer split D9: sub=SCRIPT non-canonical · em-main=governance MD)
|
||||
| Lane | Owner | Deliverable | PHẦN |
|
||||
|---|---|---|---|
|
||||
| impl-detectors | general-purpose (Write+Bash) | `scripts/governance-detectors.ps1` — C1 broken-pointer + C2 staleness(=B3) + C3 vocab-fork + C4 self-exclusion + C5 resolve-condition · NO-API grep · RUNTIME-prove | C1-C5 + B3 |
|
||||
| impl-archive-gate | general-purpose (Write+Bash) | `scripts/memory-archive-gate.ps1` (hysteresis 0.85 + keep-floor ≥5 + 2-strike + NO-API L1-eval) + budget.json A4/A5/A6 params | A1/A4/A5/A6/A7 |
|
||||
| em-main cluster | 👤 em-main | `docs/governance/harness-11-engine.md` (D1-D11 + 3-tier D5/D6/D7 + one-direction-lock D8 + trỏ detector+canonical) · B1 pointer+drift-fix (root CLAUDE.md·ef-core SKILL·skills/README·dep-audit·docs/CLAUDE.md) · cadence-wire (session-start D1·session-end D2) · agents/README ref | B1·D5-D8 |
|
||||
|
||||
## Acceptance (completeness-gate: B+C+D đủ-trọn)
|
||||
- C: 3 detector chạy được (runtime), FLAG drift thật + 0 self-match (C4)
|
||||
- B: derived count → pointer canonical; B3 detector FLAG mismatch
|
||||
- D: 3-tier + one-direction-lock codify explicit
|
||||
- Single-writer giữ: sub KHÔNG đụng canonical MD; em-main scribe
|
||||
|
||||
## Run-id
|
||||
`wf_c5e5844e-7c1`
|
||||
124
.claude/workflows/runs/2026-06-18-h11-implement/sub-task-0.md
Normal file
124
.claude/workflows/runs/2026-06-18-h11-implement/sub-task-0.md
Normal file
@ -0,0 +1,124 @@
|
||||
# sub-task-0 — `scripts/governance-detectors.ps1` (Harness-11 PHẦN C + B3)
|
||||
|
||||
> Lane **impl-detectors** · owner general-purpose (Write+Bash) · single-writer: CHỈ `scripts/governance-detectors.ps1` + file này.
|
||||
> NO-API · DÒ+FLAG-only · PowerShell 5.1 · RUNTIME-proven (output thật dán §3).
|
||||
|
||||
## 1. Deliverable
|
||||
`D:\Dropbox\CONG_VIEC\SOLUTION\SOLUTION_ERP\scripts\governance-detectors.ps1` (~355 dòng, ASCII-only body).
|
||||
3 bộ dò + self-exclusion + summary. Param `$RepoRoot` (default = `Resolve-Path $PSScriptRoot\..`). Exit-code **0 luôn** (dò-only, KHÔNG fail-build). Mỗi FLAG: `[DETECTOR] severity | file:line | desc | resolve: <điều-kiện-gỡ-cờ>` (C5).
|
||||
|
||||
## 2. Thiết-kế từng detector
|
||||
|
||||
### C2/B3 — derived-staleness (ưu-tiên, value cao nhất) ✅
|
||||
- **Canonical** đọc từ `docs/STATUS.md` CURRENT STATE table qua regex `^\|\s*<label>\s*\|\s*\*\*(\d+)` (số trong `**N**` đúng row Migrations/Tests/Gotchas/SQL tables). Runtime đọc đúng: **mig=55 test=339 gotcha=69 table=88**.
|
||||
- **Cross-check disk** (canonical tự-nó không stale):
|
||||
- `mig` = đếm `*.cs` trong **mọi** dir tên `Migrations` dưới `src` (exclude `bin|obj|node_modules` + `*Designer.cs`/`*ModelSnapshot.cs`). Recursive-search vì migration thật ở `src\Backend\SolutionErp.Infrastructure\**Persistence**\Migrations (SPEC ghi gần-đúng `...\Migrations` — đã xử robust). Runtime: disk mig=55.
|
||||
- `gotcha` = max N từ `^### (\d+)\.` trong `docs/gotchas.md`. Runtime: disk gotcha=69.
|
||||
- STATUS-value ≠ disk-value → FLAG `canonical-itself-stale` (HIGH). Lần này KHỚP → 0 HIGH (baseline an-toàn).
|
||||
- **Derived scan** 5 file: `CLAUDE.md`(root) · `docs/CLAUDE.md` · `.claude/skills/ef-core-migration/SKILL.md` · `.claude/skills/README.md` · `.claude/skills/dependency-audit-erp/SKILL.md`. Count-token regex: `(\d+)\s*migration` · `(\d+)\s*test` · `(\d+)\s*(?:<bay>|gotcha)` · `(\d+)\s*(?:<bang>|table)`. Lệch canonical → FLAG `derived-stale` (MED nếu |lệch|≥10, else LOW).
|
||||
|
||||
### C1 — broken-pointer ✅
|
||||
- **(a) gotcha-ref**: grep `docs/** + .claude/** *.md` bắt `gotcha[s]?\s*#?(\d+)` + bare `#(\d+)`. `gotcha #N` luôn validate (N>max → broken MED; thiếu `### N.` anchor → LOW). Bare `#N` chỉ xét trong range; `#N`>max bỏ qua (tránh nhầm Run #312/PR #). Runtime: **0 flag** — mọi gotcha-ref ≤69 và có anchor (đúng — repo sạch khoản này).
|
||||
- **(b) wikilink**: scan user-memory `C:\Users\pqhuy\.claude\projects\...\memory\*.md` + in-repo `.claude/agent-memory/**`. Bắt `\[\[([a-z0-9_-]+)\]\]`; target `<name>.md` không tồn tại trong scope → dangling. User-memory KHÔNG reachable → note + agent-memory-only (lần này user-memory REACHABLE, 29 file).
|
||||
|
||||
### C3 — vocab-fork ✅
|
||||
- Seed alias-set: `@('wave-folder','run-trace')`, `@('<Du tru PRO>','<Ngan sach PRO>')`, `@('two-tier','all-inherit')`. Mỗi set đếm file dùng từng biến-thể; ≥2 biến-thể CÙNG sống → FLAG count + sample | resolve gộp/alias-map.
|
||||
|
||||
### C4 — self-line exclusion (BẮT BUỘC) ✅
|
||||
- Exact: `scripts/governance-detectors.ps1`, `docs/governance/harness-11-engine.md`. Dir-fragment: `\broadcasts\inbox\`, `\broadcasts\outbox\`, `\.claude\workflows\runs\`, `\.claude\workflows\scripts\`. `Test-Excluded` áp MỌI scan. Summary in `self-exclusion: N paths excluded` + assert `self in scan=0` + `leaked=0`.
|
||||
|
||||
### 🔴 Encoding-robustness (gotcha #30 — phát-hiện lúc RUNTIME, đã FIX)
|
||||
Vòng-1 detector MISS `CLAUDE.md:133` "68 bẫy" + cả set vocab-fork `Dự trù PRO`↔`Ngân sách PRO`. Root-cause: file `.ps1` ghi **UTF-8 KHÔNG BOM** (Write-tool); `powershell.exe -File` ở PS 5.1 decode file no-BOM bằng **codepage ANSI (1252)**, KHÔNG phải UTF-8 → literal tiếng Việt `bẫy`/`bảng`/`Dự trù` bị mojibake → KHÔNG match content UTF-8 đọc đúng (`Get-Content -Encoding UTF8`). FIX: body **ASCII-only**, mọi token tiếng Việt build từ **Unicode code-point runtime** qua helper `U @(0x62,0x1EAB,0x79)` → encoding-độc-lập. Sau fix: 71 flag (vòng-1 chỉ 53 — thiếu 18 do mojibake). Đây là minh-chứng giá-trị của mandate "viết xong PHẢI chạy thật".
|
||||
|
||||
## 3. RUNTIME — output thật (`powershell.exe -ExecutionPolicy Bypass -File scripts/governance-detectors.ps1`)
|
||||
|
||||
**Exit code: 0** · **TOTAL FLAGS: 71** (HIGH=0 · MED=33 · LOW=38).
|
||||
|
||||
```
|
||||
===== C2/B3 - canonical resolve + disk cross-check =====
|
||||
STATUS.md canonical: mig=55 test=339 gotcha=69 table=88
|
||||
disk cross-check: mig=55 gotcha=69
|
||||
[OK] canonical matches disk (mig + gotcha) - safe baseline for derived scan
|
||||
|
||||
===== C2/B3 - derived-doc staleness =====
|
||||
[DETECTOR] LOW | CLAUDE.md:53 | derived-stale: writes 53 migration but canonical=55 | resolve: update to 55 OR replace with pointer '-> docs/STATUS.md' <== TRUE drift (root CLAUDE mig)
|
||||
[DETECTOR] MED | CLAUDE.md:53 | derived-stale: writes 53 gotcha/bay but canonical=69 | resolve: ... <== FALSE-POS ("53" la mig-number, dinh token 'bay'? -> thuc te dong 53 KHONG co 'bay'; xem honesty #2)
|
||||
[DETECTOR] MED | CLAUDE.md:66 | derived-stale: writes 306 test but canonical=339 | resolve: ... <== TRUE drift (root CLAUDE test)
|
||||
[DETECTOR] MED | CLAUDE.md:80 | derived-stale: writes 45 test but canonical=339 <== FALSE-POS (45 = Domain breakdown)
|
||||
[DETECTOR] MED | CLAUDE.md:81 | derived-stale: writes 261 test but canonical=339 <== FALSE-POS (261 = Infra breakdown)
|
||||
[DETECTOR] MED | CLAUDE.md:84 | derived-stale: writes 6 test but canonical=339 <== FALSE-POS
|
||||
[DETECTOR] MED | CLAUDE.md:90 | derived-stale: writes 2 test but canonical=339 <== FALSE-POS ('2 test project')
|
||||
[DETECTOR] LOW | CLAUDE.md:133 | derived-stale: writes 68 gotcha/bay but canonical=69 | resolve: update to 69 ... <== TRUE drift (root CLAUDE '68 bay') -- VONG-1 BI MISS, sau fix encoding moi bat
|
||||
[DETECTOR] MED | docs/CLAUDE.md:13 | derived-stale: writes 4 table/bang but canonical=88 <== FALSE-POS ('4 bang Budget' module-local)
|
||||
[DETECTOR] LOW | docs/CLAUDE.md:70 | derived-stale: writes 93 table/bang but canonical=88 | resolve: update to 88 ... <== TRUE drift (ERD '93 bang')
|
||||
[DETECTOR] MED | docs/CLAUDE.md:123 | derived-stale: writes 4 table/bang but canonical=88 <== FALSE-POS (Phase 7 '4 bang Budget')
|
||||
[DETECTOR] MED | docs/CLAUDE.md:124 | derived-stale: writes 71 test but canonical=339 <== FALSE-POS (Phase 8 historical '71 test')
|
||||
[DETECTOR] MED | .claude/skills/ef-core-migration/SKILL.md:3 | writes 10 migration <== FALSE-POS ('.NET Core 10 migration')
|
||||
[DETECTOR] LOW | .claude/skills/ef-core-migration/SKILL.md:3 | writes 53 migration <== TRUE drift
|
||||
[DETECTOR] LOW | .claude/skills/ef-core-migration/SKILL.md:19 | writes 53 migration <== TRUE drift
|
||||
[DETECTOR] MED | .claude/skills/ef-core-migration/SKILL.md:34..115 | writes 1/3/4/10 table/bang <== FALSE-POS (per-migration '<n> bang module ...')
|
||||
[DETECTOR] MED | .claude/skills/ef-core-migration/SKILL.md:42/86/87/154/171 | writes 1/2 migration <== FALSE-POS (mig list seq number)
|
||||
[DETECTOR] MED | .claude/skills/ef-core-migration/SKILL.md:107 | writes 58/96/154 test <== FALSE-POS (per-project breakdown)
|
||||
[DETECTOR] LOW | .claude/skills/ef-core-migration/SKILL.md:285 | writes 53 migration <== TRUE drift
|
||||
[DETECTOR] MED | .claude/skills/README.md:20 | writes 10 migration <== FALSE-POS ('.NET Core 10')
|
||||
[DETECTOR] LOW | .claude/skills/README.md:20 | writes 53 migration <== TRUE drift
|
||||
[DETECTOR] LOW | .claude/skills/README.md:90 | writes 68 gotcha/bay <== TRUE drift ('68 bay')
|
||||
[DETECTOR] LOW | .claude/skills/dependency-audit-erp/SKILL.md:153 | writes 68 gotcha/bay <== TRUE drift ('68 bay')
|
||||
(note: count-token grep is a soft net - module-local phrases like "4 bang Budget" / "71 test (Phase 8)" can false-positive; treat LOW sev as review-not-fail)
|
||||
|
||||
===== C1 - broken gotcha-ref =====
|
||||
(no flags -- all gotcha #N refs <= 69 and anchored; bare #N>max skipped to avoid Run#/PR# noise)
|
||||
|
||||
===== C1 - dangling wikilink =====
|
||||
[DETECTOR] LOW | user-memory/<29 file>:* | dangling-wikilink: [[<hyphen-form>]] -> <name>.md not found in user-memory | resolve: fix link / create file (hyphen-vs-underscore fork)
|
||||
... 21 user-memory dangling (vd [[feedback-implementer-truncation-mitigation]] -- file that la feedback_implementer_truncation_mitigation.md _underscore_) ...
|
||||
[DETECTOR] LOW | agent-memory/pattern_*.md:* | [[pattern-...-hyphen]] -> not found ... 8 agent-memory dangling (6 hyphen-fork + 2 trong 2026-06.gist.md tro feedback_* underscore khac-scope) ...
|
||||
|
||||
===== C3 - vocab-fork =====
|
||||
[DETECTOR] MED | multiple files | vocab-fork: wave-folder=15f vs run-trace=18f live side-by-side -- 'wave-folder' in [docs/HANDOFF.md, docs/STATUS.md] | 'run-trace' in [docs/HANDOFF.md, docs/STATUS.md] | resolve: merge / alias-map
|
||||
[DETECTOR] MED | multiple files | vocab-fork: Du tru PRO=7f vs Ngan sach PRO=6f live side-by-side -- in [docs/HANDOFF.md, docs/STATUS.md] | resolve: merge / alias-map <== VONG-1 BI MISS (mojibake), sau fix moi bat
|
||||
[DETECTOR] MED | multiple files | vocab-fork: two-tier=17f vs all-inherit=10f live side-by-side -- in [docs/HANDOFF.md, docs/STATUS.md] | resolve: merge / alias-map
|
||||
|
||||
===== Summary =====
|
||||
self-exclusion: 5 paths excluded (exact+dir rules)
|
||||
- excluded: scripts/governance-detectors.ps1
|
||||
- excluded: docs/governance/harness-11-engine.md
|
||||
- excluded: broadcasts/inbox
|
||||
- excluded: broadcasts/outbox
|
||||
- excluded: .claude/workflows/runs
|
||||
self-match check: governance-detectors.ps1 in scan = 0 ; leaked excluded files in scan = 0
|
||||
[OK] 0 self-match (C4 satisfied)
|
||||
|
||||
TOTAL FLAGS: 71
|
||||
NOTE: DETECT-only lowering net. Exit 0 always (never fails build). FLAGs are advisory.
|
||||
=== EXIT CODE: 0 ===
|
||||
```
|
||||
> (Output trên rút-gọn các block lặp dài; con-số tally + dòng load-bearing y-nguyên run thật. Full 71 dòng có trong stdout.)
|
||||
|
||||
## 4. Acceptance — verdict (số đo)
|
||||
| Mục SPEC | Verdict | Bằng-chứng (file:line từ output thật) |
|
||||
|---|---|---|
|
||||
| (i) C2/B3 FLAG drift root CLAUDE.md **mig 53 vs 55** | ✅ PASS | `CLAUDE.md:53 ... 53 migration but canonical=55` |
|
||||
| (i) **gotcha 68 vs 69** | ✅ PASS | `CLAUDE.md:133 ... 68 gotcha/bay but canonical=69` (sau encoding-fix) + `README.md:90` + `dep-audit/SKILL.md:153` |
|
||||
| (i) **test 306 vs 339** | ✅ PASS | `CLAUDE.md:66 ... 306 test but canonical=339` |
|
||||
| (ii) C3 FLAG vocab-fork wave↔run-trace | ✅ PASS | `wave-folder=15f vs run-trace=18f live side-by-side` |
|
||||
| (iii) self-exclusion 0 self-match | ✅ PASS | `governance-detectors.ps1 in scan = 0 ; leaked = 0 ; [OK] C4 satisfied` |
|
||||
| Exit-code 0 (dò-only) | ✅ PASS | `=== EXIT CODE: 0 ===` |
|
||||
| NO-API | ✅ PASS | Chỉ `Select-String/Get-Content/Get-ChildItem/regex`. grep script: 0 hit `Invoke-WebRequest|curl|api|http` |
|
||||
| PS 5.1 parse | ✅ PASS | `PSParser.Tokenize` 0 error |
|
||||
| Bonus drift bắt thêm | ℹ️ | `docs/CLAUDE.md:70 93 bảng` (canon 88) + vocab-fork thứ-3 `Dự trù PRO=7f vs Ngân sách PRO=6f` (rename S65 còn 2 tên sống) |
|
||||
|
||||
## 5. C5 resolve-condition — đủ mọi FLAG
|
||||
derived-stale → "update to M OR replace with pointer '-> docs/STATUS.md'" · canonical-itself-stale → "re-ground STATUS.md <row> to <disk>" · broken-gotcha-ref → "fix number or add gotcha to docs/gotchas.md" · dangling-wikilink → "fix link target or create file" · vocab-fork → "merge to ONE canonical term, or record alias-map".
|
||||
|
||||
## 6. Honest limitations (LƯỚI giảm-sót, KHÔNG khoá-cứng — đừng over-claim)
|
||||
1. **C2/B3 count-token = soft net, FALSE-POSITIVE thật**: trong 41 derived-flag, ~12 TRUE drift / ~29 FP. Nguồn FP: `.NET Core 10 migration` (version), per-project test breakdown (45/261/58/96), migration list seq number (`1 migration`), module-local `4 bảng Budget`, Phase-historical `71 test`. Mitigation: NOTE cảnh-báo + sev LOW khi |lệch|<10. KHÔNG lọc cứng theo ngữ-cảnh (giòn). Người xử FLAG, KHÔNG auto-fix. **TRUE-signal (53 mig · 306 test · 68 bẫy · 93 bảng) ĐỀU có trong list** → runtime-proof ĐẠT.
|
||||
2. **`CLAUDE.md:53 "53 gotcha/bay"` = FP do regex tham**: token `(\d+)\s*(?:bẫy|gotcha)` bắt "53" rồi nuốt khoảng-trắng dài tới chữ "gotcha" xa hơn trên cùng dòng (dòng 53 dài, có chữ `gotcha #63/#64`). → over-match. Đây là giới-hạn regex flat-line, GHI RÕ. Dòng 53 thật-sự stale ở "53 migration" (đã bắt riêng, đúng).
|
||||
3. **bare `#N` gotcha-ref** cố-ý bỏ qua khi N>max (tránh nhầm Run #312/PR #) → có thể MISS broken-ref dạng `#999` thật. Trade-off ít-noise.
|
||||
4. **agent-memory `2026-06.gist.md` 2 dangling** trỏ file user-memory (khác-scope) → "dangling trong agent-memory" kỹ-thuật đúng nhưng có thể cross-scope cố-ý. GHI nhận, không khẳng định tuyệt-đối broken.
|
||||
5. **user-memory path hard-code** theo slug máy này; máy/CI khác → tự fallback agent-memory-only + note (đã code; chưa test máy khác).
|
||||
6. **vocab-fork sample chỉ in 2 file đầu** mỗi biến-thể (gọn output); muốn full-list cần mở rộng — chấp-nhận cho lần này.
|
||||
|
||||
## 7. Single-writer compliance
|
||||
CHỈ ghi 2 file: `scripts/governance-detectors.ps1` + sub-MD này (`runs/2026-06-18-h11-implement/sub-task-0.md`). KHÔNG đụng canonical MD (CLAUDE/README/STATUS/agents) · KHÔNG agent-memory · KHÔNG sub-MD khác · KHÔNG store_memory/RAG/HTTP/Qdrant. Detector tự-nó KHÔNG ghi file nào (FLAG ra stdout only) — auto-WRITE luật = mối-nguy #1, đã tránh tuyệt-đối.
|
||||
```
|
||||
156
.claude/workflows/runs/2026-06-18-h11-implement/sub-task-1.md
Normal file
156
.claude/workflows/runs/2026-06-18-h11-implement/sub-task-1.md
Normal file
@ -0,0 +1,156 @@
|
||||
# sub-task-1 — Harness-11 PART-A — memory-archive-gate.ps1 (hot-mem auto-archive standing-gate, NO-API)
|
||||
|
||||
**Role:** general-purpose (implementer, has Write/Edit) · **Run:** 2026-06-18-h11-implement
|
||||
**Files owned (single-writer, file-disjoint):**
|
||||
- `scripts/memory-archive-gate.ps1` (NEW, 266 lines)
|
||||
- `.claude/agent-memory/memory-budget.json` (ADD `archive_gate` block only)
|
||||
- this sub-MD
|
||||
|
||||
**Verdict:** DONE + RUNTIME-PROVEN. DRY-RUN clean (A7 GATE PASS 186/186 pointers, exit 0). A6 2-strike lifecycle proven across 2 `-Apply` runs (WATCH@strike1 → PROPOSE@strike2). NO-API + FLAG-ONLY audited clean.
|
||||
|
||||
---
|
||||
|
||||
## 1. budget.json — additive params (acceptance item 1)
|
||||
|
||||
Added `archive_gate` block **before** `measured` (did NOT touch `measured` / `tiers` / `last_sleep_at` / `seeded_date`):
|
||||
|
||||
```json
|
||||
"archive_gate": {
|
||||
"_note": "Harness-11 PART-A ... ADDITIVE ...",
|
||||
"autoinject_cap_bytes": 25600,
|
||||
"low_watermark_ratio": 0.85,
|
||||
"keep_floor_entries": 5,
|
||||
"strike_threshold": 2
|
||||
}
|
||||
```
|
||||
|
||||
- `autoinject_cap_bytes: 25600` = A1 over-cap line (matches existing `tiers.l1_hot.autoinject_cap_bytes`).
|
||||
- `low_watermark_ratio: 0.85` → `floor(0.85 * 25600) = 21760` = A4 hysteresis drain target.
|
||||
- `keep_floor_entries: 5` = A5.
|
||||
- `strike_threshold: 2` = A6.
|
||||
|
||||
**Untouched-block proof (runtime):**
|
||||
```
|
||||
JSON parse OK
|
||||
archive_gate: cap=25600 low_ratio=0.85 keep_floor=5 strike=2
|
||||
measured block still present? cicd l1_hot=23653
|
||||
last_sleep_at preserved? 2026-06-18
|
||||
```
|
||||
|
||||
## 2. memory-archive-gate.ps1 — structure
|
||||
|
||||
Two independent passes, DRY-RUN by default (`-Apply` only advances the strike counter; **never** moves/edits a `.md`).
|
||||
|
||||
| Pass | Maps to | What it does |
|
||||
|---|---|---|
|
||||
| PASS 1 PLANNER | A1 / A4 / A5 / A6 | per `<sub>/MEMORY.md`: measure bytes (A1); if > cap, plan #oldest-entries to MOVE to get **below** low-watermark (A4 hysteresis), keeping ≥ keep_floor newest (A5), gated behind 2-strike (A6). Prints `sub bytes over? entries strike after-est resolve`. |
|
||||
| PASS 2 A7-GATE | A7 NO-API | per `<sub>/archive/_INDEX.md`: extract every `substring:"..."`; literal `.Contains()` search across `archive/*.md` (UTF-8); byte-sanity (file exists + size>0). Prints PASS/FAIL per pointer. |
|
||||
|
||||
Key design points:
|
||||
- **Entry boundary** (A5 counting) = first of `^##` / `^###` / `^---` (regex `^(#{2,3}\s|---\s*$)`). MEMORY.md files here are h2-only today (verified) so marker-count == entry-count; regex also tolerates h3/HR files.
|
||||
- **after-est** = `total − sum(line.Length+2)` for the moved prefix (CRLF-aware estimate; prefixed `~` to flag it as approximate — the gate never performs a real cut).
|
||||
- **A6 strike state** persisted to `.claude/agent-memory/.archive-strikes.json` (flat `{sub:int}`, ASCII). Reset-to-0 on any clean run ⇒ *consecutive*-over-cap semantics. Mutated **only under `-Apply`** so DRY-RUN is side-effect-free.
|
||||
- **A7 robustness**: resolves the substring against ALL `archive/*.md` for the sub (not just the arrow-named file) because the 3 `_INDEX` formats name the target differently (reviewer `→ \`file\``; cicd `\`file\` · substring:`; inv-codebase q-shorthand table). A unique substring landing anywhere in the sub's frozen archive == resolved. Skips `^\s*>` blockquote legend lines (the `substring:"<unique-string>"` template is documentation, not a record).
|
||||
- **Exit code**: `2` on A7 integrity failure (broken pointer / 0-byte archive); `0` otherwise. Over-cap is a FLAG, not an error (gate reports, human curates).
|
||||
|
||||
## 3. RUNTIME — DRY-RUN (canonical evidence)
|
||||
|
||||
`powershell.exe -ExecutionPolicy Bypass -File scripts\memory-archive-gate.ps1` → EXIT 0:
|
||||
|
||||
```
|
||||
============================================================
|
||||
memory-archive-gate.ps1 - Harness-11 PART-A
|
||||
mode : DRY-RUN (no writes at all)
|
||||
cap : 25600 bytes (autoinject_cap)
|
||||
low-water : 21760 bytes (A4 hysteresis drain target = ratio 0.85)
|
||||
keep-floor : 5 newest entries (A5)
|
||||
strike-need : 2 consecutive over-cap runs to PROPOSE (A6)
|
||||
============================================================
|
||||
|
||||
### PASS 1 - hot-tier over-cap planner (FLAG ONLY, no moves)
|
||||
|
||||
sub bytes over? entries strike after-est resolve
|
||||
------------------------ --------- ----- ---------- ------- ------------ -------
|
||||
cicd-monitor 26798 YES 18 1 ~21180 WATCH (strike 1<2): re-run; propose only after 2 consecutive over-cap
|
||||
database-agent 5917 no 6 0 - ok
|
||||
frontend-designer 24004 no 6 0 - ok
|
||||
harvest-curator 18952 no 6 0 - ok
|
||||
implementer-backend 17692 no 23 0 - ok
|
||||
implementer-frontend 13394 no 16 0 - ok
|
||||
investigator-api 8510 no 9 0 - ok
|
||||
investigator-codebase 31502 YES 20 1 ~27069 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
reviewer 38755 YES 14 1 ~33738 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
test-specialist 24663 no 17 0 - ok
|
||||
tooling-auditor 18431 no 6 0 - ok
|
||||
|
||||
[A6] DRY-RUN: strike counters NOT persisted (run with -Apply to advance strikes)
|
||||
|
||||
### PASS 2 - A7 archive-integrity gate (NO-API: grep + measure only)
|
||||
|
||||
[cicd-monitor] _INDEX.md + 7 archive file(s)
|
||||
-> PASS pointers 76 resolved 76 failed 0
|
||||
[implementer-backend] _INDEX.md + 7 archive file(s)
|
||||
-> PASS pointers 41 resolved 41 failed 0
|
||||
[investigator-codebase] _INDEX.md + 7 archive file(s)
|
||||
-> PASS pointers 40 resolved 40 failed 0
|
||||
[reviewer] _INDEX.md + 5 archive file(s)
|
||||
-> PASS pointers 29 resolved 29 failed 0
|
||||
|
||||
------------------------------------------------------------
|
||||
A7 GATE PASS - total pointers 186, resolved 186, failed 0
|
||||
------------------------------------------------------------
|
||||
EXITCODE=0
|
||||
```
|
||||
|
||||
**Reads the spec's expected over-cap subs:** reviewer 38755 (~37.8KB, over), investigator-codebase 31502 (~30.8KB, over). cicd-monitor 26798 also over (current, > spec's stale ~note). All 8 under-cap subs print `ok`.
|
||||
|
||||
## 4. RUNTIME — A6 2-strike lifecycle (`-Apply` ×2)
|
||||
|
||||
The strike-counter is an **executed-file** mechanism; it needs 2 runs to demonstrate the PROPOSE gate (honest n"executed-file vs runtime" tier).
|
||||
|
||||
**APPLY run 1** → strikes file written `{cicd:1, inv:1, reviewer:1, all-clean:0}`; over-cap subs show `WATCH (strike 1<2)`:
|
||||
```
|
||||
cicd-monitor 26798 YES 18 1 ~21180 WATCH (strike 1<2): re-run; propose only after 2 consecutive over-cap
|
||||
investigator-codebase 31502 YES 20 1 ~27069 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
reviewer 38755 YES 14 1 ~33738 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
[A6] strikes persisted -> ...\.archive-strikes.json
|
||||
```
|
||||
|
||||
**APPLY run 2** → strikes advance to 2; cicd-monitor flips WATCH → **PROPOSE** (it has drainable headroom: move 6 oldest → ~21180 < low-water 21760); inv/reviewer stay WARN (A5 keep-floor priority — newest 5 entries alone exceed cap):
|
||||
```
|
||||
cicd-monitor 26798 YES 18 2 ~21180 PROPOSE archive (strike 2>=2): move 6 oldest -> curate L1->L2 by hand
|
||||
investigator-codebase 31502 YES 20 2 ~27069 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
reviewer 38755 YES 14 2 ~33738 WARN keep-floor hit (5); cannot auto-drain - SPLIT/condense entries by hand
|
||||
```
|
||||
strikes file after run 2: `{cicd:2, inv:2, reviewer:2, all-clean:0}`.
|
||||
|
||||
**Strike artifact cleaned up** post-test (`rm .archive-strikes.json`) — DRY-RUN default never creates it; shipped repo carries no stale strike state. Cold-start DRY-RUN re-verified: EXIT 0, A7 GATE PASS 186/186.
|
||||
|
||||
## 5. Bugs hit + fixed during build (honesty log)
|
||||
|
||||
1. **PS 5.1 parser cascade (mid-build, self-fixed):** line 94 had a typo `'resolve")` — a `"` where a `'` belonged — which left a single-quoted string unterminated and consumed forward, throwing 4 misleading errors anchored at *later* valid lines (102/222/233/266). Root-caused via per-line `0x22`-byte hexdump (`xxd | grep 22`) → the closing `'` of the last `-f` arg was a `"`. Fixed → `'resolve')`. Lesson: PS 5.1 mis-locates the error site of an unterminated string; bisect by counting quotes, not by trusting the reported line.
|
||||
2. **gotcha #30 mojibake (A7 false-FAIL):** first A7 run reported 55 PTR-FAILs, all on pointers containing Vietnamese diacritics / em-dash / arrows (`â€"`, `×`, `â†'`). Cause: PS 5.1 `Get-Content` / `Select-String` default to ANSI codepage and mangle UTF-8. Fix: read BOTH `_INDEX.md` and archive files via `[System.IO.File]::ReadAllText($path, UTF8)` + `String.Contains()` → 189/190 resolve. This **is the gotcha #30 trap the precedent script's "ASCII-only" header warns about**, hit from the read side.
|
||||
3. **legend-line false-positive (true-positive catch):** cicd `_INDEX.md:4` blockquote documents the format with literal `substring:"<unique-string>"`; my regex matched it (77 vs the index's self-declared 76 real pointers). Added `^\s*>` skip → clean 76/76. The gate correctly distinguished a non-record from a broken pointer.
|
||||
|
||||
## 6. Acceptance checklist evidence
|
||||
|
||||
| Item | Verdict | Evidence |
|
||||
|---|---|---|
|
||||
| (1) NO-API | PASS | grep audit: only `Set-Content` is the strikes int-map (line 177); zero http/curl/api/model/qdrant calls. `.md` files are read-only. |
|
||||
| (2) FLAG-ONLY / no auto-write of rules | PASS | DRY-RUN header "no writes at all"; over-cap = printed FLAG; no Move/Edit of any MEMORY.md or archive. `-Apply` writes only the counter. |
|
||||
| (3) PowerShell .ps1, `-ExecutionPolicy Bypass` | PASS | runs via `powershell.exe -ExecutionPolicy Bypass -File`; ASCII-only output; PS 5.1 parse OK. |
|
||||
| (4) RUNTIME-prove | PASS | DRY-RUN output §3 (exit 0) + 2× `-Apply` strike lifecycle §4 pasted from real runs. |
|
||||
| (5) sub writes only file-disjoint + sub-MD | PASS | `git status --porcelain` after cleanup = only `M memory-budget.json` + `?? memory-archive-gate.ps1` (+ this sub-MD in run-folder). No canonical MD touched. |
|
||||
| A1 measure | PASS | bytes column real (reviewer 38755 etc.). |
|
||||
| A4 hysteresis | PASS | drains to BELOW low-water (cicd after-est ~21180 < 21760), not to the line. |
|
||||
| A5 keep-floor | PASS | inv/reviewer WARN "keep-floor hit (5); cannot auto-drain" — refuses to vét-sạch. |
|
||||
| A6 2-strike | PASS | run1 WATCH(1<2) → run2 PROPOSE(2>=2); strikes file 1→2; reset-on-clean. |
|
||||
| A7 pointer-resolve + byte-sanity | PASS | 186/186 across 4 subs w/ archive; UTF-8 round-trip; legend-line skipped. |
|
||||
|
||||
## 7. Tailoring declared (PART-A = 🟡 tailorable)
|
||||
|
||||
Documented inline in the script `[TAILOR]` footer block:
|
||||
- **after-est is an ESTIMATE** (`line.Length+2` CRLF heuristic, `~` prefixed) — real bytes only known post-move, which the gate deliberately never does.
|
||||
- **Entry boundary** = first of `^##`/`^###`/`^---` (today's files are h2-only → exact; tolerant of other styles).
|
||||
- **A6 strike** = flat `{sub:int}` JSON, consecutive semantics via reset-on-clean, requires 2 real `-Apply` runs to reach PROPOSE (matches spec "runtime needs 2 runs").
|
||||
- **A7** resolves substring against ALL `archive/*.md` for the sub (the 3 index formats name targets differently) + skips `>` legend lines.
|
||||
Reference in New Issue
Block a user