All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 10m12s
Phiên governance thuần, 0 code product. Bookend @close chạy trọn 1 lượt (YC-018/YC-027). 14 vai: H1 8 FLAG · H2 GATE-FAIL 6 · cặp H24 deep (10+7 FLAG) · trio 3/3 (MIXED 38 trục → 4 action/18 BÁC → 50Đ/5T/15KC trên 70 claim) · ring1 41Đ/5T/19KC · ring2 15Đ/0T/2KC · ring5 1Đ/2 xoá-án/1KC · ctx-audit TRUOT 6 FLAG · tầng-2/3 chấm. Vá đã land: - 3 ô SỐ canonical STATUS: Mig 73→74 · test 697→699 (45+654) · gotcha 92→93; bổ 3 ô vào ledger WAL TRƯỚC khi vá; lan Mig 74 sang CLAUDE.md + docs/CLAUDE.md. - CG-1 attempt #1: cứu front-end-reviewer-style 1.192→5.913 B (clobber-rot, 4 chứng; harness-audit xác nhận md5 nối thuần, 0 mất). - Trả nợ harvest S188 4 vai/42.975 B; đóng orphan S194 bằng synthesis hồi-tố. - Vá gốc dòng rách so-yeu-cau:58-59 => máy đổi muc 28→29, hội tụ đếm tay. - Đính chính tiền-đề SAI reinject-ledger:70 cho CẢ HAI vai (matcher DÍNH-vs-TÁCH). - MIND-4 => mind-check --closed từ exit 1 sang exit 0. 3 RCA lỗi của lead: FAKE-VERDICT-S195 (verdict bịa cho vai chưa chạy) · RITUAL-ECHO-S195 (tái phạm lần 3) · SCORE-T1-S195 (đọc hụt số máy). #53 nổ 10 lần, cứu 10/10 bằng resume-in-session. 4 vai tự phát hiện thước hỏng của chính mình — không có bước tự-falsify thì lượt này có >=7 cáo buộc oan. completeness-gate S195: vong 4/5 chuc-nang (khong-nhip: V4) | phep DAT 3 / TRUOT 1 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
147 lines
17 KiB
Markdown
147 lines
17 KiB
Markdown
# REINJECT-LEDGER — Harness-17 CG-1 termination ledger (SOLUTION_ERP)
|
||
|
||
> **Sổ-ghi chốt-dừng (termination) cho vòng tự-cải-thiện bộ-nhớ (Harness-17 §I).** Ghi mỗi lần một **mục-sàn floor-rot** (đã-từng-ở-hot-mem nay RỚT) được **reinject verbatim** trở lại L1 — để **CG-1** chặn reinject-loop vô-hạn.
|
||
>
|
||
> 🔴 **Vì sao file RIÊNG (không nhét vào `memory-budget.json`):** `memory-budget.json` = **quyền cấp-ngân-sách của anh (project-owner)** — MFE + audit chỉ **đọc** `token_governor`, KHÔNG ghi (ranh-giới §G.4(4), mark `RC-…21-06…01-58-01`). Trộn reinject-state vào đó = AI lấn quyền cấp-ngân-sách. Ledger này = **git-tracked · append-only · single-writer em-main (D9)** — mirror provenance-model của [`ACTIVE-MARKS.md`](ACTIVE-MARKS.md). NEVER overwrite dòng cũ.
|
||
|
||
## CG-1 rule (chốt-dừng — H17 mục B2)
|
||
|
||
- Mỗi `item-id` được **reinject TỐI-ĐA 1 lần trong N phiên** (SE solo-dev: **N = 3**). N nhỏ hơn multi-dev vì solo = 1 người-điều-phối, feedback-loop nhanh (đủ 3 phiên để work-state block bơm lại "ngấm").
|
||
- Sau reinject, phiên MFE kế **đo-lại**: nếu mục ĐÃ hiện diện lại trong L1 → `status=resolved`, **đóng chu-kỳ** (KHÔNG reinject nữa).
|
||
- Nếu đo-lại **VẪN thiếu** → **KHÔNG** tự-reinject lần-2 (KHÔNG ghi `attempt=2`). Thay vào → `status=escalated` + **báo anh (project-owner)**: có thể **build-gap** (cơ-chế bơm chưa đủ — cần extend) HOẶC cần anh quyết **tăng-budget / đổi-placement** (mirror MFE H3 2-ca: thiếu-CHỖ→tăng-budget-anh-quyết vs rot→sắp-xếp-lại). AI **KHÔNG** tự-loop.
|
||
- **Chỉ floor-rot mới vào ledger này** (phân-loại qua phép-thử B3 §I): item **ĐÃ-từng-tồn-tại ∩ CÒN-giá-trị ∩ RỚT-khỏi-L1**. Item chưa-từng-dựng = **build-gap** (đi dựng cơ-chế, KHÔNG reinject). Item hết-giá-trị = để **cold-archive** (rớt đúng-đắn).
|
||
|
||
## Schema (mỗi dòng = 1 chu-kỳ reinject; append newest xuống cuối)
|
||
|
||
| Cột | Nghĩa |
|
||
|---|---|
|
||
| `item-id` | id ổn-định mục-sàn rớt (RC-sig · `AS-N` · `gotcha #N` · guard-name) |
|
||
| `source` | file canonical chứa verbatim (`ACTIVE-MARKS.md` · `error-ledger.md` · `gotchas.md`) |
|
||
| `detected` | phiên MFE/audit phát-hiện floor-rot (`S<NN>`) |
|
||
| `reinjected` | phiên em-main reinject verbatim (`S<NN>`) |
|
||
| `attempt` | lần thứ mấy (rule ≤1 trong N=3; nếu cần lần-2 → **escalate**, KHÔNG reinject) |
|
||
| `remeasured` | phiên MFE đo-lại sau reinject (`S<NN>`) |
|
||
| `status` | `reinjected` → `resolved` (đo-lại đủ) HOẶC `escalated` (đo-lại vẫn thiếu → anh quyết) |
|
||
|
||
> **Cách đọc (ví-dụ minh-hoạ — KHÔNG phải dòng thật):**
|
||
> `| gotcha #57 | docs/gotchas.md | S96 | S96 | 1 | S97 | resolved |` = chu-kỳ đóng đúng: S96 audit FLAG gotcha #57 rớt khỏi L1 → em-main APPEND verbatim từ `gotchas.md` → S97 đo-lại thấy lại → `resolved`, dừng.
|
||
> Chu-kỳ **escalate**: reinject `attempt=1` @S96 → S97 đo-lại VẪN thiếu → `status=escalated`, báo anh (build-gap? tăng-budget? đổi-placement?) — KHÔNG ghi `attempt=2`.
|
||
|
||
## Ledger (append-only — single-writer em-main)
|
||
|
||
| item-id | source | detected | reinjected | attempt | remeasured | status |
|
||
|---|---|---|---|---|---|---|
|
||
| _(chưa có floor-rot nào được reinject — ledger khởi-tạo trống S95, 2026-07-01)_ | | | | | | |
|
||
|
||
---
|
||
|
||
> **Nấc honest:** ledger = **convention** (em-main append tay, git-tracked audit-trail — KHÔNG OS-hook auto-write, nhất-quán CAVEAT engine "no-OS-hook"). Tín-hiệu floor-rot feed = **mechanized** (`mfe-eval.ps1` age-band + `memory-selfimprove-audit.ps1`). Detection per-item-L1-presence hiện **partial** (MFE age-band chỉ đo marks-có-date; AS/guard/gotcha mang session-ref chưa có pass so-từng-item-trong-L1 — xem §I honest nấc + CAVEAT C4 self-blind-spot).
|
||
|
||
---
|
||
|
||
## Re-verify: presence-not-age selector (broadcast `ab6c387e`, adopt S115 · 2026-07-13)
|
||
|
||
> AI_INFRA broadcast `ab6c387e` (type=**update**) — re-verify the memory refine-step **selector** decides by PRESENCE/COVERAGE, not AGE. Verdict per floor:
|
||
|
||
- **(i) Reinject = MET (presence-based).** Trigger = **floor-rot** `"ĐÃ-từng-ở-L1 ∩ CÒN-giá-trị ∩ RỚT-khỏi-L1"` (coverage-gap, this file `:12`) = the broadcast (i) condition "should be present but is missing." Age plays no part in *what-to-reinject*. The CG-1 `reinjected` session column is a **reinject-event rate-limiter / loop-breaker (≤1 per N=3 sessions), NOT an age-rank** → OK per broadcast (iii) carve-out ("date used only for last-seen/loop-breaking = OK"). Drop-date test: dropping the column changes only the rate-limit/termination count, never the selection.
|
||
- **(iii) MFE age-band = FLAG-only (COMPLIANT).** `mfe-eval.ps1` `$oldN` is computed then `Write-Host`-printed ("KEPT status-driven age-blind") with **no downstream consumer**; the denominator is gated by STATUS, not date. Drop-date test: changes one diagnostic count, not the denominator / FIT / Goodhart / any selection.
|
||
- **(ii)+(iii) Archive-gate = RED-FLAG surfaced → HARDENED (D3, S115).** The planner's oldest-by-position base ordering tripped the (iii) self-check; fixed in `scripts/memory-archive-gate.ps1` by promoting `value_protect` from an advisory post-hoc flag to a **pre-selection HARD-SKIP** (value-primary; position = within-low-value tiebreak) + a value-floor WARN. Fault-injection-verified (protected-not-drained + permutation-invariant + value-floor). See `memory-budget.json:value_protect._note`.
|
||
|
||
**BUILD-GAP (honest, disclosed):** mechanized **per-item-L1-presence** detection is still PARTIAL — the MFE age-band counts *present* marks (by date), not per-item *drops*; AS/guard/gotcha carrying session-refs have no per-item-in-L1 pass yet. So reinject-detection stays **convention + em-main judgement**, not full mechanization (do NOT overclaim). Consistent with §I honest nấc + CAVEAT C4.
|
||
|
||
**3 honest-notes (broadcast §5 — MANDATORY):**
|
||
1. Basis = **ONE** occurrence already fixed elsewhere → **proactive-prevention**, NOT a spreading SE incident.
|
||
2. **SPECIFIC-APPLICATION**, not a new rule — SE reinject + MFE age-band were already presence/flag-based (quick re-verify, no change); only the archive-gate needed hardening.
|
||
3. Floor = **FUNCTION not FORM** — implemented in SE's own script shape; no hub structure/filenames copied.
|
||
|
||
> **Provenance:** `/fable-clone reviewer` 5-lane ensemble (`wf_b621aac4-f0b`) → spec `runs/2026-07-13-presence-not-age-adopt/spec-presence-not-age-adopt-13-07-2026.md` → `/fable-real reviewer` deep-pass (PASS-WITH-FIXES; M1+M2 applied) → HMW execute D1/D2/D3. Applies existing mark `RC-…10-29-11` (age=false-proxy) to the selector layer; codify-only (no new mark).
|
||
|
||
---
|
||
|
||
## S185 (2026-08-10) — 2 mục MFE MISS lần đầu CÓ TÊN ⇒ phân loại B3 = **BUILD-GAP, KHÔNG reinject**
|
||
|
||
**Bối cảnh:** `-Detail` được cắm vào `session-end §L.b(c)` @YC-019(6) (switch tồn tại từ đầu, **0 call-site suốt 12 phiên**). Lần chạy đầu tiên có cờ này, 2 mục MISS thoát khỏi trạng thái vô danh:
|
||
|
||
| Vai | Điểm | Mục MISS (nguyên văn máy in) | Nhà trong role-file |
|
||
|---|---|---|---|
|
||
| `implementer-backend` | 17/18 = 94% | `❌ Integration testing multiple components` | `.claude/agents/implementer-backend.md:34` (auto-refuse #5) |
|
||
| `implementer-frontend` | 12/13 = 92% | `❌ < 30 min trivial` | `.claude/agents/implementer-frontend.md:31` (auto-refuse #6) |
|
||
|
||
**Phân loại B3 (bắt buộc TRƯỚC reinject) = BUILD-GAP, không phải floor-rot.** Bằng chứng đo: `grep -ci` trên diary 2 vai = **0/0** — 2 mục này **chưa bao giờ xuất hiện rồi rơi**; chúng chưa bao giờ được **kích hoạt**. Lý do cơ chế: "integration test nhiều component" ở SE luôn về `test-specialist` (ranh vai), còn "< 30 min trivial" thì lead tự làm chứ không spawn sub ⇒ 2 vai **chưa từng gặp ca để từ chối**.
|
||
|
||
🔴 **Quyết định: KHÔNG reinject-verbatim.** Nhồi 2 dòng này vào diary sẽ đẩy 94%→100% / 92%→100% mà **không thêm một giá trị nào** — đúng hình dạng Goodhart mà `feedback_goodhart_leave_measurement_set` mô tả: đổi hình-dạng thứ đang bị đo thay vì đổi thực-chất. CG-1 (≤1/N=3) **không tiêu quota** vì không có sự kiện reinject nào.
|
||
|
||
**Hệ quả phải khai khi đọc số MFE về sau:** trần thực tế của 2 vai này **< 100% cho tới khi có ca thật** — 94%/92% ở đây đọc là *"chưa gặp ca"*, KHÔNG phải *"trí nhớ rot"*. Ai thấy số này rồi "vá" cho tròn 100% là đang xoá **chứng nhân**, không phải xoá lỗi.
|
||
|
||
**Điều-kiện lật (làm cho phán quyết này falsifiable):** nếu về sau một trong 2 vai **thực sự từ chối** một task bằng đúng tiêu chí đó mà diary vẫn 0-hit ⇒ lúc ấy mới là **floor-rot thật** ⇒ reinject theo CG-1.
|
||
|
||
---
|
||
|
||
## CG-1 attempt #1 — `front-end-reviewer-style` · REINJECT THI HÀNH (2026-08-14, S195)
|
||
|
||
**Phân loại B3 = FLOOR-ROT**, sub-class MỚI: **`clobber-rot`** (rơi do bị ĐÈ, không do drain). Đây là **lần đầu tiêu quota CG-1** — sổ trước đó 0 dòng reinject.
|
||
|
||
**Trigger:** `harness-eval` §3 trục #14 + `harness-refine` A1 — `.claude/agent-memory/front-end-reviewer-style/MEMORY.md` **4.721 B → 1.192 B = −3.529 B (−74,8%)** tại commit `e470bddf`.
|
||
|
||
**4 bằng chứng độc lập chốt là CLOBBER, không phải curate:**
|
||
1. Cùng commit `e470bddf` chạm **9 diary — 8/9 là APPEND THUẦN** (`+7 −0`, `+10 −0`; +1.154…+1.690 B). Riêng 1/9 là **`+5 −17`**. Cùng một thao tác seed, 8 con làm đúng ⇒ **ý định là append**.
|
||
2. Commit đó **KHÔNG tạo file archive nào** (`--name-status`: 2 file `A` đều thuộc `.claude/sessions/`) ⇒ 3.529 B **không đi đâu cả**.
|
||
3. **Mất luôn dòng H1.** Quét 29 diary: **đúng 1/29** có dòng đầu không phải H1 — chính con này. **28/29 sạch = control dương**, thước có phân giải.
|
||
4. **Blob còn nguyên** tại `e470bddf^` = 4.721 B ⇒ **hồi phục được, KHÔNG mất trắng**.
|
||
|
||
**Cái mất là loại đắt nhất, không phải log:** LUẬT LÕI nguyên văn của owner (*"tính năng đã deploy production là chuẩn, trừ khi tao chỉnh lại"*) · toàn bộ **địa phận/ranh vai** (`fe-admin/src/**` + `fe-user/src/**`; soi style không soi logic) · bản vá thước dispatch **SỬA-1** (thứ quyết định vai **có được gọi hay không**) · 2 bài citation-trap. Vai vẫn sống (`.claude/agents/front-end-reviewer-style.md` 12.960 B) ⇒ lần spawn tới nó vào việc **không còn định nghĩa địa phận lẫn luật owner**, mà diary chỉ còn *một ghi chú rằng nó đã chết*.
|
||
|
||
**Thi hành:** **UNION trên đúng 1 path** — `git show 'e470bddf^:<path>'` + append nội dung hiện có.
|
||
🔴 **BÁC `git revert e470bddf`** (`harness-refine` BÁC-14): revert sẽ **xoá entry S194** (ghi nhận một lần vai chết = dữ liệu thật), **lật ngược 8 file anh em đã append ĐÚNG**, và đụng 2 file `.claude/sessions/`.
|
||
|
||
**Verify sau thi hành (4 phép, đo tươi):** `wc -c` = **5.913 B** — 🔴 **khớp BYTE-EXACT dự đoán 5.913 B của `harness-refine`** · H1 `# front-end-reviewer-style Agent — Persistent Memory` đã về · `grep -c '^## S194'` = **1** (không nhân đôi, không mất) · `grep -c 'SINH SỔ … SỬA-5a'` = **1** (nội dung cũ không lặp) · 3 hit các mục load-bearing kể trên.
|
||
Bản cũ chứa **0 hit `S194`** ⇒ UNION an toàn by-construction, không đếm đôi.
|
||
|
||
**CHỐT-DỪNG (theo `harness-refine`):** attempt = **1**, lần đầu trên vật này. Tick sau nếu file **< 5.800 B** HOẶC vẫn thiếu H1 ⇒ **ESCALATE lead, CẤM attempt-2**.
|
||
|
||
**Nợ KÈM — thuộc lead, KHÔNG phải corpus (ES-3):** **đường ghi** đẻ ra clobber này (Write đè thay vì append) lọt qua nghi thức vì thước hiện tại là *"byte > 0"* mà **1.192 > 0** ⇒ **guard có, nhưng mù đúng sub-class mới**. Luật phân biệt đã ghi: *L1 co lại mà **0 file L2 sinh trong cùng commit** + **mất H1** = clobber, KHÔNG phải curate*.
|
||
|
||
---
|
||
|
||
## 🔴 ĐÍNH CHÍNH TIỀN-ĐỀ SAI của dòng `:70` — phán bởi `harness-audit` @S195, lead nhận
|
||
|
||
**Dòng `:70` (mục MFE @S185) khai:** *"grep -ci trên diary 2 vai = 0/0 — 2 mục này **chưa bao giờ xuất hiện rồi rơi**"* ⇒ phân loại **BUILD-GAP** cho CẢ HAI vai. **Tiền-đề này SAI cho CẢ HAI**, mỗi vai sai một kiểu.
|
||
|
||
### (a) `implementer-backend` — SAI vì mục ĐÃ BỊ CHÍNH LANE REFINE DỜI ĐI
|
||
|
||
`implementer-backend/archive/2026-07.md:18` nguyên văn:
|
||
```
|
||
## @S152 R1 retention-note [moved-not-cut @S185 refine-A1, verbatim]
|
||
```
|
||
`:19` = mục `Integration testing multiple components` — **chính mục MFE báo MISS**. Chuỗi nhân quả đóng kín: **@S152** vai ghi vào L1 → **@S185 `refine-A1`** (hành động của chính lane refine) dời L1→L2 → **@S185 ledger** phán build-gap bằng grep **chỉ quét L1, và L1 rỗng VÌ A1 vừa dọn** → **@S192** MFE 18/18→17/18.
|
||
Control-dương đóng vòng: L1 = **0** · `archive/2026-07.md` = **1** · 14 file archive khác = **0**.
|
||
⇒ Phân loại đúng = **FLOOR-ROT**. `mfe-eval.ps1:243` (nguồn mục = role-file) + **`:264`** (diary = **CHỈ** `MEMORY.md`) ⇒ **archive tàng hình với MFE by construction**.
|
||
|
||
### (b) `implementer-frontend` — SAI vì MATCHER MÙ, không phải vì mục không tồn tại
|
||
|
||
🔴 **`harness-refine` ES-4 định GIỮ NGUYÊN phán quyết build-gap cho vai này. `harness-audit` bác bằng đĩa:**
|
||
```
|
||
.claude/agents/implementer-frontend.md:31 6. ❌ < 30 min trivial <- mục denominator
|
||
implementer-frontend/MEMORY.md:54 "2 ranh auto-refuse: việc <30min/trivial = em-main solo"
|
||
implementer-frontend/archive/2026-H2.md:80 "(a) Việc < 30 min / trivial: … REFUSE nhận đúng
|
||
role-file; nhận việc trivial = đốt spawn vô ích."
|
||
```
|
||
Mục này **ĐANG SỐNG Ở L1 HÔM NAY**, còn có bản đầy đủ ở L2. *"Chưa từng sống"* **SAI**. Và cơ-chế biện minh kèm theo (*"lead tự làm chứ không spawn sub ⇒ vai chưa từng gặp ca để từ chối"*) cũng đổ: `2026-H2.md:80` là **đúng một ca từ chối có lý do**.
|
||
|
||
**Vì sao máy vẫn báo MISS — cơ-chế, không phải bí ẩn:** matcher `mfe-eval.ps1:281-287` đòi **≥2 content-word là alnum-run RỜI** (`(?<![a-z0-9])…(?![a-z0-9])`). L1 viết **DÍNH**: `<30min/trivial` ⇒ `30min` là **MỘT** run ⇒ `30` và `min` **đều trượt lookaround** ⇒ chỉ còn `trivial` = 1 từ < `minWords 2` ⇒ **MISS**. Đây đúng cơ-chế **DÍNH-vs-TÁCH** đã ghi @S173 — **tái phát nguyên vẹn**, và lần này bị đọc nhầm thành *"chưa từng tồn tại"*.
|
||
|
||
### 🔴 Hệ quả — HÀNH ĐỘNG giữ nguyên, LÝ DO phải đổi
|
||
|
||
**KHÔNG reinject cho cả hai** — nhưng nền lý lẽ đổi hẳn:
|
||
- ~~"chưa từng sống ⇒ build-gap"~~ **SAI**.
|
||
- **Nền đúng:** nội dung **ĐÃ được mang rồi** (backend ở L2 sau A1 copy-về; frontend ở cả L1 lẫn L2) ⇒ nhồi thêm là **Goodhart thuần**: đẩy 92%→100% với **0 thông tin mới**. Đúng cảnh báo `harness-audit` đã ghi @S173: *"cách RẺ NHẤT đẩy 92%→100% là viết chuỗi `30` đứng riêng vào diary"*.
|
||
- ⇒ Đây là hình dạng **quen thuộc S189/S192: ĐÚNG KẾT LUẬN, SAI LÝ DO**. Nếu ES-4 thi hành y văn thì sổ governance sẽ mang **một mệnh đề sự thật SAI, tồn tại lâu dài**.
|
||
|
||
### Vai tự nghi trước khi kết tội (giữ vì đây là chuẩn)
|
||
`harness-audit` chạy **F16** (*"probe `30 min` của tao có lỏng, bắt oan refine không?"*) và **F17** (*"`<30min/trivial` có khác nghĩa mục 6 không?"*) — dùng control-dương trên backend (1 hit đúng file, 0 chỗ khác) **và đọc NGUYÊN VĂN** cả 2 dòng thay vì tin số đếm. **Cả 2 HELD.**
|
||
|
||
### Khuyết tật thước KÈM (chưa vá, thuộc owner/tooling)
|
||
1. **`git ls-tree`/`git archive` KHÔNG dùng được cho trục byte trên kho này** — `measure-agent-memory.ps1:14` dùng `(Get-Item).Length` = **ĐĨA**, git normalize CRLF→LF nên blob **luôn hụt đúng số dòng**. Đo: `reviewer` disk **28.804** ⟂ blob **28.673**, delta **131** = **CRLF pairs 131**, khớp tuyệt đối. **8/29 diary là `w/crlf`.** Công thức đúng: `disk = blob + LF_count nếu w/crlf`.
|
||
2. **`mfe-eval.ps1` KHÔNG IN dòng tổng nào** — `grep 'roles_scored\|numerator\|denominator'` trong script = **0 hit**; `163/165 = 98,79%` là số **gộp tay**, **chưa bao giờ là output máy**. ⇒ signal #7 của con-ĐO (*"MFE dòng tổng vắng khỏi bề mặt"*) sẽ đẩy lane refine đi đòi lead dán **một dòng không bao giờ tồn tại**. Verdict *"không tự kiểm được dưới C1"* ĐÚNG, **nguyên nhân SAI**.
|
||
3. **`-Tier sub` là đường READ-ONLY** của `mfe-eval.ps1` (dispatch `:329` `Measure-Lead` chứa write ⟂ `:330` `Measure-Sub`) — chứng bằng **md5 trước = sau** (`58ebfd05…`, mtime bất biến), không bằng đọc code. Mở lại đường chạy mà @S192 vai từng **từ chối**.
|