[CLAUDE] Docs: S153 closeout — adopt TRỌN Ctx soft-memory + OWNER-VETO 3-vai + RENAME hub-form (squash 22 wal:)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m39s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m39s
Pipeline anh lệnh: /check-email + /adap-apply -> /fable-real invest (spec 9-task/24-checklist) -> hmw Opus-5-MAX 2 đợt + lead-solo T6-T8 -> checklist verify. Thư ① 9c909007 (model-default Opus 5 MAX): TRỌN — filing 2-tuyến + probe-sau-restart 2-nguồn claude-opus-5[1m] + thư hub d432f5eab5cd + caveat (e) đóng. Thư ② 0df10df4 (pause-tiep Ctx soft-memory, sàn 7-khoản): EXECUTED - máy mind-check: scripts/session_ctx.py +542 dòng (7 phép + 2 phụ, 4 mức, draft/closed/--root/--session PIN, exit 0/1/3) - template .claude/templates/session-mind-template.md + wire 4 lệnh (pause C-bis+2bis+§1-carve-out, tiep §2.6+§3-ter, session-start Phase 3.5, session-end §L.b(l)+6.3-bis) - memory-budget: mind_ctx_kb=32 + tiep_reload + ĐÓNG ghost-wire session_ctx_kb (H18 class-2 sống S146->S153) - fault-inject 18/18 + 2 fix hậu-T4 (FI 6/6): GAP-#9 closed-mode E-0-con-trỏ CỜ->TRƯỢT (chặn gradient thưởng xoá-con-trỏ-trung-thực, họ bẫy F-1 của chính thư hub) · secrets-sweep +--root parity - số ĐO THẬT pause +117ms thay ước lệch 2.2-5.4x OWNER 2 quyết trong-phiên: - (38) VETO: 1-vai -> hub-form 3-vai (ctx-curator @pause + carve-out pause §1 · ctx-verifier @tiep · ctx-audit @2-bookend) - RENAME theo chuẩn hub/sisters để audit chéo: ctx-pause-check->ctx-curator, ctx-reload->ctx-verifier (đo đĩa 3 nhà; hub≠sister => SE theo HUB-form, tiền lệ S149). Roster 20->23, VALID_ROLES 23. Gap còn lại: ring5-audit (V5 truth-floor) hub CÓ, SE+VIPIX chưa -> slot (41). Bookend 2 đầu (12 spawn) + trio auto 1 vòng: - @open: H1 7f · H2 4f · H24 5+3 FLAG · ring1 28Đ/4T · ring2 8/8Đ + M-1 MISS thật · trio eval-MIXED-14/refine-3A-7B-4N/audit-25Đ-3T (re-chạy 7 instrument, 24 số byte-exact) - @close: H1 6f · H2 8f (baseline S154 = 16/10, tự sửa bản ~23/11) · H24 4+2 FLAG · ring1 47Đ/5T/1KC/53 · ring2 6/6Đ + 21 phép phụ - lead xử 11 mục: 9 FLAG H24 + 3 RESIDUAL ring2 + F-r2 (plugin 3 hard-site) + M-1 cả 2 persona + M9 14 sổ diary + F-3/F-5/F-6 + nit Sàn-5 + BÁC F-4 (fan-out không vào _index) #53 x14-cận-dưới, 0 mất dữ liệu (WRITE-lane derive-from-body · Agent-resume · SendMessage-resume x6). Datum: trio return-only hết miễn nhiễm (3/3 CLEAN -> 1/3). 4-A suýt xảy ra thật (bản committed của 2 file H24 là bản cắt 24%/48%). completeness-gate: 5 vòng đủ · phép ĐẠT 4 / TRƯỢT 0 / vacuous 0. State: Mig 67 · 89 bảng · 532 test · gotcha 83 · Sub-agents 23 · counter 27 · bundle FROZEN · governance-only 0 prod-code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
{
|
||||
"strikes_total": 25,
|
||||
"rca_entries": 14,
|
||||
"at": "2026-07-25",
|
||||
"at": "2026-07-26",
|
||||
"warn_baseline": 25,
|
||||
"history": [
|
||||
{
|
||||
@ -28,6 +28,11 @@
|
||||
"strikes_total": 25,
|
||||
"rca_entries": 14,
|
||||
"at": "2026-07-25 23:55"
|
||||
},
|
||||
{
|
||||
"strikes_total": 25,
|
||||
"rca_entries": 14,
|
||||
"at": "2026-07-26 11:52"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
12
.claude/agent-memory/ctx-audit/MEMORY.md
Normal file
12
.claude/agent-memory/ctx-audit/MEMORY.md
Normal file
@ -0,0 +1,12 @@
|
||||
# ctx-audit Agent — Persistent Memory
|
||||
|
||||
- **S153 (2026-07-26) SINH RA + RENAME cùng phiên — vai-3 vòng Ctx `[seed on-behalf by lead @closeout M9 — mày CHƯA chạy lần nào; nguồn = đĩa, KHÔNG tái-dựng từ trí nhớ]`:** adopt thư hub `0df10df4` (pause-tiep-upgrade-vong-ctx, sàn 7-khoản lớp mềm). Đường sinh: `/fable-real investigator-codebase` deep-pass → spec 9-task ([`spec-ctx-adopt-26-07-2026.md`](../../workflows/runs/2026-07-26-S153-ctx-adopt/spec-ctx-adopt-26-07-2026.md)) → hmw Opus-5-MAX T3 tạo persona (11/11 acceptance, 14.347B) → **T10 OWNER-VETO**: bản đầu (38)(a) cho mày GỘP 3 nhịp hub thành 1 vai; anh hỏi *"còn thiếu 2 vai ctx?"* rồi chốt **"Build đủ 3 vai như hub"** ⇒ mày THU về **vai-3 thuần** (soi CHUỖI 2 đầu + mồi-ngầm + block-0 @open + **kiểm-VẾT vai-1/vai-2**); hồi-tố 5-khoản/4-khoản hạ thành **FALLBACK** (chỉ khi phiên 0-pause/0-tiep) → **T11 RENAME** theo lệnh anh *"đặt tên giống hub và sisters để dễ audit"*: 2 vai anh em `ctx-pause-check`→**`ctx-curator`** · `ctx-reload`→**`ctx-verifier`** (tên mày GIỮ — đã đúng hub-form; VIPIX gọi vai này `ctx-chain`, hub≠sister ⇒ SE theo HUB, tiền lệ S149 `lead-*`).
|
||||
**Nấc THẬT của mày:** `file-land + registry-surfaced @S153` — **spawn-probe ALIVE CHƯA CÓ** (T9 phiên sau restart CLI). Lượt chạy đầu cũng ở T9 (dogfood 4-cửa). Wire: `session-start` Phase 3.5(iii) @open · `session-end` §L.b(l) @close.
|
||||
**Máy TRƯỚC mày (đọc, KHÔNG re-implement):** `python scripts/session_ctx.py mind-check --session <N>` — 7 phép + 2 phụ, 4 mức {đạt·trượt·cờ·bỏ-qua-có-khai}, exit {0,1,3}; fault-inject **18/18 PASS** @T4 + **6/6** sau 2 fix hậu-T4. Trần = khoá `mind_ctx_kb` (=32KB, OWNER-DELEGATED→LEAD-DECIDED @S153, B1 CẤM chép số vào persona).
|
||||
**2 fix hậu-T4 đáng nhớ (chúng là RĂNG của mày):** (1) **GAP-#9** — closed-mode "mục E có nội-dung mà 0 con-trỏ" CỜ→**TRƯỢT**: nếu để CỜ thì *xoá con-trỏ đang-chờ* (→ nhánh 0-con-trỏ, exit 0) RẺ HƠN *giữ trung thực* (pending→TRƯỢT) ⇒ gradient thưởng đường SAI, đúng họ bẫy F-1 mà chính thư hub §4 kể. (2) `secrets-sweep` +`--root` seam parity (2 lưới độc-lập cùng phủ `_mind`).
|
||||
**Kẽ mày PHẢI khai khi chạy:** mồi-ngầm single-lead chỉ đạt **xuyên cửa-sổ** (fresh window không nhớ ý nào là mồi) · máy KHÔNG canh bất-biến block per-run (cần git-history — lưới = luật + git + mày so-git khi nghi) · tên-tệp-sai trong thư-mục thật đọc thành "đang-chờ" tới cửa đóng mới siết.
|
||||
Tag `[s153, sinh-ra, owner-veto-3-vai, rename-hub-form, vai-3-soi-chuoi, gap-9-fix, chua-spawn-probe]`
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
|
||||
> Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
|
||||
> **NEW agent S153 (2026-07-26)** — vai-3 vòng Ctx (soi chuỗi lớp mềm 2 đầu phiên); 2 vai anh em: `ctx-curator` (@pause) · `ctx-verifier` (@tiep).
|
||||
12
.claude/agent-memory/ctx-curator/MEMORY.md
Normal file
12
.claude/agent-memory/ctx-curator/MEMORY.md
Normal file
@ -0,0 +1,12 @@
|
||||
# ctx-curator Agent — Persistent Memory
|
||||
|
||||
- **S153 (2026-07-26) SINH RA — vai-1 vòng Ctx `[seed on-behalf by lead @closeout M9 — mày CHƯA chạy lần nào; nguồn = đĩa]`:** sinh bởi **OWNER-VETO @S153** — anh bác phương án 1-vai-gộp, chốt trực tiếp qua AskUser *"Build đủ 3 vai như hub"* (đây là **owner chốt THẬT**, KHÔNG phải delegated — đừng ghi nhầm nhãn). Khai-sinh tên `ctx-pause-check`, **RENAME `ctx-curator` CÙNG PHIÊN** theo lệnh anh *"đặt tên giống hub và sisters để dễ audit"* (đo đĩa 3 nhà: **hub** = `ctx-curator`/`ctx-verifier`/`ctx-audit` · **VIPIX** = `ctx-check`/`ctx-reload`/`ctx-chain` · hub≠sister ⇒ SE theo **HUB-form**, đúng tiền lệ anh ratify @S149 khi rename `lead-stale-auditor`/`lead-gap-auditor`).
|
||||
**Việc của mày:** KIỂM **bản NHÁP** block `## MIND-<k>` @MỖI `/pause`, **SAU** máy `mind-check --draft` (máy-$0 ~61ms lo lỗi cơ-học: 3 rào literal + số-hiệu; mày lo tầng **máy MÙ** = NGỮ-NGHĨA), **TRƯỚC** khi lead chèn vào `_mind-s-<N>.md` — dịch-trái: lỗi bắt ở nháp là lỗi KHÔNG BAO GIỜ vào tệp bất-biến. 5 khoản: A-E đủ/trống-có-khai · E phủ đủ mọi spawn cửa-sổ này · đã-chốt=con-trỏ · 3 rào tầng ngữ-nghĩa (lời anh bị PARAPHRASE lách rào-1 · secret dạng mới lách pattern) · nhãn D đúng THỰC-TRẠNG (ý đã chốt trong WAL mà còn `đang-cãi` ⇒ điểm SỬA).
|
||||
**Chỗ đứng đặc biệt:** mày là **carve-out DUY NHẤT** của `pause.md §1 "NGỪNG spawn"` (mirror hub O-1(a)) — carve-out này KHÔNG tồn tại ở phương án 1-vai; nó sinh ra cùng lúc với mày. Wire: `pause.md §2.6(C-bis)` bước **2-bis**.
|
||||
**Nấc THẬT:** `file-land @S153` — **spawn-probe ALIVE CHƯA CÓ** (T9 phiên sau restart CLI). Chi phí pause đo thật: máy +117ms, mày = +1 spawn (~100K tok floor) — **núm hạ tần suất để sẵn cho anh** (1 câu là hạ nhịp/tắt; máy-$0 vẫn lo). Trả **CHỈ văn bản** ≤12 dòng, dòng-1 `CTX-CURATOR: DAT|SUA|SKIP-CO-KHAI — <n> điểm`; lead sửa nháp, KHÔNG phải mày.
|
||||
**Bài học sẵn có để không lặp:** persona `lead-stale-auditor.md:51-54` từng dạy nhịp CŨ (cadence) sau khi hình-B đã đổi — ring2 bắt @S153 (M-1). ⇒ mày viết nhịp ở dạng **KHẲNG ĐỊNH hiện hành**, không chép khuôn retired.
|
||||
Tag `[s153, sinh-ra, owner-veto-3-vai, rename-hub-form, vai-1-nhap-@pause, carve-out-pause-§1, chua-spawn-probe]`
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
|
||||
> Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 `archive/` on-demand · L3 RAG just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
|
||||
> **NEW agent S153 (2026-07-26)** — vai-1 vòng Ctx; anh em: `ctx-verifier` (@tiep) · `ctx-audit` (@2-bookend).
|
||||
12
.claude/agent-memory/ctx-verifier/MEMORY.md
Normal file
12
.claude/agent-memory/ctx-verifier/MEMORY.md
Normal file
@ -0,0 +1,12 @@
|
||||
# ctx-verifier Agent — Persistent Memory
|
||||
|
||||
- **S153 (2026-07-26) SINH RA — vai-2 vòng Ctx `[seed on-behalf by lead @closeout M9 — mày CHƯA chạy lần nào; nguồn = đĩa]`:** sinh bởi **OWNER-VETO @S153** (anh chốt trực tiếp *"Build đủ 3 vai như hub"* qua AskUser = **owner chốt THẬT**, không phải delegated). Khai-sinh tên `ctx-reload`, **RENAME `ctx-verifier` CÙNG PHIÊN** theo lệnh anh *"đặt tên giống hub/sisters để dễ audit"* — 🔴 lưu ý nghịch-lý dễ nhầm: **VIPIX gọi vai này ĐÚNG là `ctx-reload`** (trùng tên khai-sinh của mày), nhưng **hub** gọi `ctx-verifier`; luật SE = **hub-form khi hub≠sister** (tiền lệ S149 `lead-*`) ⇒ tên mày theo hub.
|
||||
**Việc của mày:** @MỖI `/tiep`, **SAU** máy `mind-check` full (~55ms), làm **4 khoản đối-chiếu** rồi trả **BẢN NẠP-LẠI ≤15 dòng**: (1) mục B hướng-tiếp vs WAL `next:` — lệch ⇒ 🔴 **TIN SỔ MÁY** + giương cờ (WAL = sổ chốt; `_mind` = lớp mềm) · (2) mục C kế-hoạch vs bản-đồ việc (WAL chain + run-folder + STATUS §In Progress) · (3) ý mục D đã ĐỊNH-ĐOẠT mà chưa đổi nhãn ⇒ cờ (đổi nhãn = việc lead ở block kế) · (4) con-trỏ mục E — đọc verdict 3-trạng-thái của máy, KHÔNG tự phán lại.
|
||||
🔴 **Dòng BẮT BUỘC cuối return:** `LEAD-PHAI-NHAC-LAI: <tên-ý-D> · <E-verdict>` — đây là **bằng-chứng NỘI-DUNG** của sàn khoản 3 thư hub: lead phải nhắc lại chi tiết chỉ-biết-nếu-đã-đọc; câu "đã nạp" suông KHÔNG tính, metadata ts/hash KHÔNG tính. Thiếu dòng này = sàn khoản 3 thành khai suông.
|
||||
**Ranh:** KHÔNG nạp NỀN hộ lead — nạp nền = nghi-thức LEAD theo khoá `tiep_reload` (mode `rut-gon`, ~40-60K tok; nền-full SE đo tươi **596.316B ≈ 149-199K tok**, nặng hơn nền hub 1.36× nên rút gọn là quyết (37)(b)). Mày CHỈ lo lớp mềm.
|
||||
**Nấc THẬT:** `file-land @S153` — **spawn-probe ALIVE CHƯA CÓ** (T9 phiên sau restart CLI); lượt chạy đầu = dogfood 4-cửa @T9. Wire: `tiep.md §3-ter`.
|
||||
Tag `[s153, sinh-ra, owner-veto-3-vai, rename-hub-form-nghich-ly-vipix, vai-2-nap-lai-@tiep, lead-phai-nhac-lai, chua-spawn-probe]`
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
|
||||
> Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 `archive/` on-demand · L3 RAG just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
|
||||
> **NEW agent S153 (2026-07-26)** — vai-2 vòng Ctx; anh em: `ctx-curator` (@pause) · `ctx-audit` (@2-bookend).
|
||||
@ -1,5 +1,11 @@
|
||||
# harness-audit — MEMORY (bộ-ba đồng-kiểm memory, nấc 3/3: con KIỂM)
|
||||
|
||||
- **S153 (07-26) trio vòng AUTO — con KIỂM `[lead seed on-behalf @closeout M9; nguồn = harness-audit-return.md]`:** **25 ĐẠT / 3 TRƯỢT / 1 KHÔNG-CHẤM trên 29 claim** · falsify **16 phép: 12 HELD / 4 BROKE** · **re-chạy 7 instrument, 24 số eval cite → 0 lệch**. Lượt-1 GARBLE #53 (return-only, 0 đĩa) → resume trả trọn.
|
||||
**3 TRƯỢT (đều bắt bằng phép mạnh hơn lời khai):** T1 eval "PIN↔LIVE 5/7" = SAI, thật **4/7 khớp / 3 lệch** (bảng của chính eval đã liệt 3 dòng lệch ⇒ tự-mâu-thuẫn; meta-count blind-spot) · T2 refine A2 "6/19" = SAI, thật **5/19**, work-list THIẾU 1 file (`tooling-auditor/archive/2026-06.gist.md` — có chuỗi `coverage` nhưng là **prose** `:26` "N/A có-chủ-đích (coverage-diff)" ⇒ probe lỏng đọc mention thành block; chạy y-văn 13 file = bỏ sót IM-LẶNG; tử-số phủ thật 26,3% không 31,6%) · T3 **LẬT 2 BÁC B2/B3** của refine — số đúng byte-exact nhưng nền suy-luận vỡ (gist harvest TỰ KHAI `+7427B NGOÀI scope` ⇒ hụt 31,4%; gist cicd scope "20 run-records" vs **0** `Run #` trên src).
|
||||
**Claim mạnh nhất xác-nhận (N2 refine):** C11(b) filter `sub-*.md` + regex `^sub-<role>[-.]` (`:1760`/`:1783`) + 3 vai trio ĐỀU `INFORM-only` (⇒ enrolled `$informRoles`) + artifact tên `harness-*-return.md` ⇒ **KHÔNG BAO GIỜ khớp**; folder có `sub-lead-*`/`sub-ring2-*` nên `$c11Measured=true` ⇒ caveat "MEASURED NOTHING" **KHÔNG in** ⇒ **đọc thành sạch**. Diary-seeding của chính bộ-ba = vùng KHÔNG được đo.
|
||||
**Quy-trình:** tuần-tự HELD (mtime-chain 12:21 → 12:36 → sau) · lead scribe §2.1.9(c) ĐẠT (2 file đúng tên/chỗ, ghi RỜI 15 phút ⇒ không batch cuối) · ⚠️ điểm yếu cấu-trúc **return-only = 0 đĩa để vớt** nếu chết hẳn (tái-hiện lần 7-8 trong wave).
|
||||
Tag `[s153, 25d-3t-29claim, 16-falsify-4-broke, re-chay-24-so-0-lech, n2-c11b-diem-mu-trio, t3-lat-2-bac-refine]`
|
||||
|
||||
## Role baseline
|
||||
Con KIỂM của bộ-ba đồng-kiểm memory-system (adopt AI_INFRA 2026-07-18 khuôn 5-câu `58e28bae`). Read-only INFORM-only + verify-độc-lập: ĐỌC run-folder PIN đích-danh (CẤM tự tìm 'run mới nhất'; pin missing/rỗng → TRƯỢT/từ-chối, CẤM ĐẠT-ảo) → TRẢ verdict ĐẠT/TRƯỢT per-claim + falsify-log HELD/BROKE + tự RE-CHẠY ≥2 số load-bearing đối-chứng byte-exact vs con-ĐO cite. Chạy CUỐI (TUẦN TỰ, sau eval+refine). Propose-only, single-writer = lead.
|
||||
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
# harness-eval — MEMORY (bộ-ba đồng-kiểm memory, nấc 1/3: con ĐO)
|
||||
|
||||
- **S153 (07-26) trio vòng AUTO — con ĐO `[lead seed on-behalf @closeout M9; nguồn = harness-eval-return.md 10.966B]`:** **MIXED — 14 signal**. Return **CLEAN lượt-1** (counter-datum: trio return-only CLEAN ×3 phiên liên tiếp S151/S152/S153-eval; nhưng refine+audit cùng phiên GARBLE ⇒ **trio hết miễn nhiễm**, n=3 không còn là "an toàn").
|
||||
**Provenance 2-lane tự dựng:** PIN 8 file instrument + **LIVE re-run 7/8** (bỏ `mfe-eval.ps1` CỐ Ý vì nó GHI `.mfe-state.json` — đúng caveat `read_only_scope`) ⇒ **4/7 byte-exact, 3/7 LỆCH THẬT** trong CÙNG phiên (nhipno light 1/6→0/6 · detector INFORM 4→6 · selfimprove HCV N/A→GAP:MED) ⇒ **bản chụp instrument có hạn dùng ngắn hơn một phiên** (S7).
|
||||
**Trục nặng:** S1 REGRESSION duy nhất — headroom **181.228 < target 210.000** (thiếu 28.772; hotload 596.316B; sàn-file phình ~58% vs mốc S115) ⇒ **ràng-buộc ĐỔI CHỦ**: trước target bó, giờ headroom bó · S2 cicd l2_index 19.322/20.480 = **94,3%** (headroom 1.158B, vai TĂNG-mỗi-run) · S4 lead-gap tái-phình **+1.489B (+9,0%)/~1 ngày** sau drain A1 ⇒ đo ĐỘ BỀN của memory-op · S6 trục TUỔI gist **0/8 instrument đo** (budget tự khai 6 cặp stale "CHUA CO MAY") · S9 diary-0-delta ×2 · S13 `pull-cach` in số mà `pull_warn_days` **không có key** ⇒ nhánh cảnh-báo không thể kích.
|
||||
🔴 **Lỗi CỦA MÌNH (audit T1 bắt):** khai "5/7 byte-exact, 2 lệch" trong khi chính bảng của mình liệt **3 instrument lệch** ⇒ tự-mâu-thuẫn nội-bộ; 14 datapoint đo NGOÀI đều đúng, chỉ con-số **ĐẾM-VỀ-MÌNH** sai — đúng lớp meta-count blind-spot.
|
||||
Tag `[s153, mixed-14-signal, s1-rang-buoc-doi-chu, pin-vs-live-3-lech, meta-count-dem-ve-minh-sai]`
|
||||
|
||||
## Role baseline
|
||||
Con ĐO của bộ-ba đồng-kiểm memory-system (adopt AI_INFRA 2026-07-18 khuôn 5-câu `58e28bae`). Read-only INFORM-only: ĐỌC output 5 instrument (`measure-agent-memory.ps1` · `mfe-eval.ps1` · `memory-archive-gate.ps1` · `crystallized-backfill.ps1` · `nhip-no-probe.ps1`) + `memory-budget.json` baseline → TRẢ số NGUYÊN-VĂN + so-baseline + verdict {HEALTHY|REGRESSION|MIXED} + đề-xuất-signal. KHÔNG hành-động, KHÔNG tự sửa, KHÔNG chấm. Propose-only, single-writer = lead.
|
||||
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
# harness-refine — MEMORY (bộ-ba đồng-kiểm memory, nấc 2/3: con ĐỀ-XUẤT)
|
||||
|
||||
- **S153 (07-26) trio vòng AUTO — con ĐỀ-XUẤT `[lead seed on-behalf @closeout M9; nguồn = harness-refine-return.md 9.792B]`:** **3 action (1 promote / 2 distill) + 7 BÁC + 4 NHƯỜNG**. Lượt-1 **GARBLE #53** (narration 1 câu) — return-only nên **0 đĩa để vớt** ⇒ SendMessage-resume trả trọn; audit CHỨNG resume không mất dữ liệu bằng nội-dung chỉ-có-khi-chạm-đĩa (2168/16565/101/78 · regex `SEV ` · `:1760`).
|
||||
**3 action:** A1 nén header `_INDEX` cicd (2.168B prose 0-pointer → ~600B + thay `Total 78 records` bằng con-trỏ A7-count; **khai thẳng đây là attempt-2 trên đối-tượng D1@S152**, tái-vượt ⇒ CẤM attempt-3 → escalate owner) · A2 append COVERAGE-TOKENS **13 gist** (audit T2 sửa thành **14** — mình đếm 6/19 có, thật 5/19; probe khớp-lỏng đọc prose `(coverage-diff)` thành block) · A3 promote luật **"proxy mtime/ngày ⇒ CẤM neo action; phải mở file so NỘI-DUNG"** vào diary chính mình.
|
||||
🔴 **Chạm đĩa lật ngược 3 ứng-viên CỦA CHÍNH MÌNH** (B2/B3 content-check + B4 persona/regex) — chỉ đọc số eval thì đã đề-xuất 2 action dương-giả + 1 sai-gốc. **B4 truy GỐC đáng nhất:** 2/4 FLAG-khuôn THẬT đã có class-tag, trượt regex CHỈ vì literal **`SEV `** (detector `:1752` đòi `— (LOW|MED|HIGH)` ngay sau em-dash); gốc = **2 nguồn khuôn đá nhau** (persona `:66` dạng-ống ⟂ detector đòi heading; hint viết `SEV` KHÔNG đóng ngoặc như `<class>` nên vai chép nguyên chữ) ⇒ diary = quyền-lực thứ-3, NHƯỜNG lane tooling.
|
||||
🔴 **Audit T3 LẬT 2 BÁC của mình:** B2 gist harvest — 3 hit `S140` đều là **tem-provenance tự-trỏ**, và chính `:4` TỰ KHAI `+7427B NGOÀI scope` ⇒ hụt 13.474B (**31,4%**) = coverage-hole THẬT self-declared · B3 gist cicd — scope khai "20 run-records" mà verbatim **0 occurrence `Run #`** ⇒ scope⟂cấu-trúc. **Bài:** so-nội-dung bằng **grep-nhãn** vẫn chưa đủ phân-giải; nấc đúng = so **scope/stamp tự-khai** vs `wc -c` src (⇒ A3 phải nâng mức khi ghi).
|
||||
Tag `[s153, 3-action-7-bac-4-nhuong, b4-truy-goc-sev-literal, audit-lat-2-bac-cua-minh, grep-nhan-khong-du-phan-giai]`
|
||||
|
||||
## Role baseline
|
||||
Con ĐỀ-XUẤT của bộ-ba đồng-kiểm memory-system (adopt AI_INFRA 2026-07-18 khuôn 5-câu `58e28bae`). Read-only INFORM-only: INPUT = `harness-eval-return.md` PIN đích-danh (missing/rỗng → TỪ-CHỐI, fail-closed) + `reinject-ledger.md`. TRẢ action 4-LỚP {①reinject điều đã rơi · ②promote bài-học lặp≥2 · ③archive bớt-nóng L1→L2 · ④distill nén} — mỗi action neo {đối-tượng file:path · trigger = số con-ĐO · chốt-dừng · owner-gate}. Propose-only, single-writer = lead.
|
||||
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
# Harvest-Curator Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) 2 LƯỢT bookend — vòng V1 harvest `[lead seed on-behalf @closeout M9; nguồn = 2 sub-file đĩa]`:** @open GATE-PASS-WITH-FLAGS 4f (0 orphan/57 · corruption 16/10 + đề **m#20** mẫu-số-có-mệnh-đề-loại-trừ · 0-byte = 10 `.gitkeep` · Fidelity byte-exact 67056 · FLAG-A/B S152 ĐÓNG · tự bắt `grep -P` chết rc=2 im-lặng ⇒ chuyển perl byte-mode). @close **GATE-PASS-WITH-FLAGS 8f**: 5-trục {Coverage PASS-with-debt · Completeness PASS · **Fidelity STRONG** · Placement PASS · Corruption PASS} · **0 orphan/59** (3 dir không-`run.md` KHÔNG orphan: 2 spec-only S117 + `S144-bootstrap` có `bootstrap-synthesis.md` — ca tự trượt @S151) · **Sàn-5 3/3 đăng-ký** (WAL `run=` 0 toàn sổ, session-log §6 gánh 4 dòng `wf:`) · **spawn-record 20 lượt** (brief ước ≈15) · **baseline S154 = 16/10** (tự SỬA bản "~23/11" của mình — ring1 @open HELD: file dùng ASCII `<FFFD>` KHÔNG đếm) · M9 3 vai ctx **ĐÃ seed, GAP-3 lần đầu đóng NGAY trong phiên sinh vai** (6 lần trước hồi-tố).
|
||||
**4 method mới:** **m#20-bis** perl `END{}` chạy 1 lần/batch xargs ⇒ TỔNG đúng mà TÊN FILE bịa hoàn toàn (tự bắt khi đo) · **m#21** END-line có ≥2 khuôn (văn-xuôi vs HTML-comment ⇒ grep 1 khuôn ra dương-giả "no END") · **m#22** cùng-size PHẢI md5 mới phán copy-vs-re-chạy · **m#23** vắng ở `git status` = đã-commit HOẶC bị-ignore ⇒ cần `ls-files --error-unmatch` + `check-ignore` mới phân biệt.
|
||||
**Nợ của chính mình:** L1 **17.655B > self-target 17.1KB** ⇒ self-compact DUE phiên sau (khối S150+S151).
|
||||
Tag `[s153, gate-pass-8f, 0-orphan-59, san5-session-log-ganh, baseline-16-10-tu-sua, m20bis-m21-m22-m23, self-compact-due]`
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
|
||||
> Update BEFORE every stop. Tiered Memory v1: **L1 self-target ≤17.1KB (hook read-limit 24.4KB)** · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars.
|
||||
> **NEW agent 2026-06-07** (adopt AI_INFRA Harness 1 — H2 harvest-integrity; TÁCH khỏi tooling-auditor H1 per anh-mandate "H1/H2 hay quên+nhầm → riêng-biệt").
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
# Implementer-Backend Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) arc ctx-adopt T1 + T3 (2 lượt hmw đợt-1) `[lead seed on-behalf @closeout M9; T1 return mất schema-fail → derive-from-body; T3 return CLEAN]`:** **T1 máy `mind-check`** — EXTEND `scripts/session_ctx.py` (+528 dòng, ADD-only: `_TS_KEY_RE` module-level canonical + subcommand + parser + dispatch; 2 subcommand cũ BẤT ĐỘNG). 7 phép + 2 phụ · 4 mức {đạt·trượt·cờ·bỏ-qua-có-khai} · draft/closed/`--root`/`--session` PIN · exit {0,1,3}. **9 quyết-định thiết-kế có lý-do đo được**, đắt nhất: **D1 config đọc LAZY** — chỉ đọc `memory-budget.json` khi CÓ tệp để đo, vì 2 dòng acceptance chỉ đồng-thời đúng theo thứ tự đó ("không có gì để đo thì không đọc trần; có thứ để đo thì TỪ CHỐI đoán trần") · D3 marker VẮNG ⇒ quét TRỌN + CỜ (hướng hỏng NGHIÊM: tệp thiếu marker = tệp sai khuôn, phải lộ) · D4 rào-3 in pattern-name + `file:line` **KHÔNG in snippet** (gate chống rò không được tự rò ra log) · D6 `_ascii_safe()` backslashreplace (console cp1252 gặp diacritic ⇒ `UnicodeEncodeError` = máy chết GIỮA gate).
|
||||
**T3 persona `ctx-audit`** 11/11 acceptance (14.347B): CHỈNH-1 của lead landed đúng nấc (`tools:` = **mô-tả ý-định**, backstop thật = git-diff commit-gate) + verify 2 chiều `grep -c 'chặn-bằng-thiếu-tool'` = 0 (cụm đó sống ở `harness-eval.md:60`, KHÔNG carry sang) · M-1 hình-B **từ lúc sinh** (đọc `lead-stale-auditor.md:51-54` CHỈ để tránh, 0 chữ chép). **5 phát hiện thêm:** vai tự nhập lưới INFORM-only của detector khi file land (`:1721-1742` đọc LIVE frontmatter) · PHẦN-B #22 sẽ FIRE THẬT nếu lead scribe mà chưa seed diary · H25 parse greedy ⇒ `sub-ctx-audit-open` UNMAPPED không flag (no-name-guessing) · C11(a) `$roleNameRx` KHÔNG áp ctx-audit ⇒ đúng khi persona không bắt gắn class-tag.
|
||||
Tag `[s153, t1-mind-check-extend-python, d1-config-lazy, d4-khong-in-snippet, t3-persona-11-11, tu-nhap-luoi-inform-only]`
|
||||
|
||||
- **S139 (07-17) Governance wave adap-3-bản 2-lane [wf_f9981ae5-903 · L1 CLEAN · L2 #53-garble → sub-1.md ON-BEHALF em-main verify-2-nguồn] `[engine: opus-worker]`:** L1 = MASTER-CHECKLIST 2-tầng in 4 cửa (ss Phase-3 · se Phase-4 "TỔNG-HỢP CHỐT" · pause ý-6 · tiep §3-bis bold-block KHÔNG heading) + C1 2-câu đóng-băng bề-mặt-đo (§L.b(c) prepend + mirror §2.1.2) + C6i do-record ×2 + luật-số sàn-5 §L.b(j)(iv) — PASS 6/6 (heading 26/28/7/14 bất-biến · 0 checklist-file mới · BƯỚC-0 intact ×8 · 10/10 config-token preserved · add-only 26+/2−). L2 = +C6 cite-2-nấc + H24-4 pending-flip vào governance-detectors.ps1 (+260/0 add-only) — fault-inject **13/13 2-chiều** (C6 7/7 lane chạy; H24-4 6/6 em-main hoàn tất — lane chết GIỮA fix harness-bug), live-run TOTAL 45 GIỮ + 2 net mới 0-flag count-riêng + exit-0 + ASCII 0-byte>127 + clean-diff 0-FOREIGN-line. Learned: (1) heading-invariant proof = block chèn toàn `>`/bullet + `grep '^+#'`=none (mạnh hơn đọc-mắt, họ insertion-only S134); (2) test-harness PS1 cần CÙNG kỷ-luật naming như production — bẫy `$h`/`$H` case-insensitive cắn chính harness dù script-đích đã né (`:813`); (3) 2 lane cùng chạm bề-mặt-đo (L1 sửa file nằm trong scan-scope L2) → số đo giữa-chừng trôi, clean-diff PHẢI cùng-snapshot. Tag `[s139, adap-3-ban, master-checklist-4-cua, c6-cite-2-nac, h24-4-pending-flip, faultinject-13-13, 53-writelane-onbehalf]`
|
||||
|
||||
- **S134 (07-17) PE lũy kế TẠM TÍNH BE [wf_58302bd5-b9f INV-2.A · return sạch 0-garble] `[engine: opus-worker]`:** +`ComputePendingAsync` + `PePendingAccumulation` (PeBudgetAccumulator.cs pure-add +68/0) + `PePendingPriorPeDto` + `PeBudgetSummaryDto` append-cuối 5 field (2 construction site: `:946` frozen-defaults 0/0/0/0/null · `:985` live-fill) + D4 audit-note TRONG `ApplyBudgetSnapshotOnFinalizeAsync` (Action=**Update** KHÔNG Transition — #49 tránh UI đọc 2 lần chuyển-phase; insertion-only +30/0; signature GIỮ → 5 call-site 0-diff, site cuối line-shift :1112→:1142 content bất động). Build slnx 0/0 · 0 mig · ComputeAsync body 0-diff (A1). Learned: (1) **insertion-only diff (grep `'^-'` = 0 real-removal) = bằng-chứng MẠNH NHẤT "thân method/call-site bất động"** — mạnh hơn đọc-mắt, chống báo-số-sai kiểu #53; (2) derived-audit thêm vào helper KHÔNG cần đổi signature nếu tính nội bộ từ field entity sẵn có (giữ call-site 0-diff); (3) accumulator ns ≠ DTO ns (`...Dtos`) → cần using tường minh dù cùng project. Tag `[s134, pe-luyke-tam-tinh, computepending, insertion-only-proof, d4-changelog-update-not-transition]`
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
# Implementer-Frontend Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) arc ctx-adopt T2 + T5 (2 lượt hmw) `[lead seed on-behalf @closeout M9; T2 return mất schema-fail (#53 +1) → derive-from-body, template VẪN LAND 8.819B; T5 return CLEAN]`:** **T2 template** `.claude/templates/session-mind-template.md` — 3 marker (RULES-START/END · MIND-TOP) · **0 dòng key `ts:`** (ts sống trong HEADING sau em-dash ⇒ không phạm rào-2) · 6 hit `rào-` (3 rào × tên+lý-do) · chiều chèn **NGƯỢC** `_context` khai TO trong khối luật · placeholder `<k>` trong schema-comment chống parser false-match (mirror trick template `_context:32`) · kiểm `_SECRET_RES` để ví-dụ rào-3 không tự khớp mẫu (secrets-sweep rglob TRỌN session-dir, KHÔNG biết enclosure).
|
||||
**T5 `hmw.js`** 3/3 acceptance: VALID_ROLES 20→21 (sau T10/T11 = **23**) + 🔴 **writeGuard là 2 ĐIỂM không phải 1** — `:228` JS-comment doc **và** `:235` template-literal ĐI VÀO PROMPT sub; chỉ sửa `:235` ⇒ doc lệch trong CÙNG file, chỉ sửa `:228` ⇒ **prompt runtime KHÔNG đổi** ⇒ vai read-only bị hướng-dẫn như write-sub ⇒ Bash-write MD ⇒ mojibake G-009. `:235` = **điểm có RĂNG**. Vùng CẤM đo bằng diff: `WIDTH_CAP` 0 hit · `TIER2_EXPECTED_FULL_ID` 0 hit.
|
||||
**2 kẽ báo lead:** ① **naming-collision cùng-role 2-invocation** (index `i` reset mỗi invocation ⇒ đợt-2 suýt đè `sub-implementer-frontend-1.md` của đợt-1; tự né bằng `-2`, verify đợt-1 nguyên 2020B) — kẽ CÒN LẠI sau S134 (S134 chỉ vá ca 2-role-cùng-invocation) ② `node --check` file thô **luôn** SyntaxError (top-level await) ⇒ acceptance phải là **wrapped-parse + đối-chứng HEAD**, không phải check thô.
|
||||
Tag `[s153, t2-template-0-ts-key, t5-writeguard-2-diem-235-co-rang, naming-collision-cung-role-2-invocation, node-check-tho-vo-nghia]`
|
||||
|
||||
- **S134 (07-17) PE lũy kế TẠM TÍNH FE 2-app [wf_58302bd5-b9f INV-2.B · return sạch 0-garble] `[engine: opus-worker]`:** types ×2 +5 field `pending*` (DIVERGE — edit riêng từng app cùng old_string sau `budgetFrozen`; grep 1/1) · PeDetailTabs `5534addb`→**`d28eaa16`** ×2 IDENTICAL: `BudgetSharedNumCell:1184`+`BudgetColValue:1197` +**`sub?: ReactNode` prop** → sub-dòng amber "Tạm tính" row1/2 (withDetail "+X từ N phiếu chưa duyệt", N8 count-TƯƠNG-ỨNG delta KHÔNG list.length) + row5/6 (gọn) + block liệt kê `pendingPriorPes` dưới matrix (plain+Badge `PurchaseEvaluationPhaseLabel`, N9 KHÔNG link — 403 S89) + gate `showPending = !bs.budgetFrozen && (...)` `?? `-guard data cũ · PeWorkflowPanel `a83a58e1`→**`bebc0ada`** ×2: banner M2-gate `!readOnly && phase === PurchaseEvaluationPhase.ChoDuyet` (enum-constant) + reminder trong Dialog `isApproveAction` TRÊN price-picker; disabled-condition 0-diff (B3 grep). npm ×2 PASS (user `index-BVoJX7QA` 20.9s · admin `index-mcHk0pmo` 9.3s). Learned: (1) **`sub?: ReactNode` slot-prop trên cell-component dùng chung = chèn sub-dòng vào N render-site không nhân bản markup**; (2) hmw đánh index sub-file GLOBAL theo taskList (backend=0, frontend=1 → `sub-implementer-frontend-1.md`) — hết collision S133 khi 2 role KHÁC nhau cùng invocation. Tag `[s134, pe-luyke-tam-tinh, sub-slot-prop, n8-count-per-delta, global-tasklist-index]`
|
||||
|
||||
- **S133 (07-17) PE budget-freeze FE types+badge [wf_d9639faa-97a INV-A, return sạch]:** 4 file — types 2-app +`budgetFrozen: boolean` (fe-user `:333` · fe-admin `:331` — 2 file KHÔNG mirror nhưng block PeBudgetSummary nội-dung identical → 1 old_string dùng chung cả 2); PeDetailTabs 2-app byte-identical: badge amber `🔒 Ngân sách chốt tại thời điểm duyệt` @ header `PeBudgetSummaryTable` `:1350-1359` (div `bg-[#1F7DC1]` → +flex justify-between; `normal-case tracking-normal` OVERRIDE `uppercase tracking-wide` của header; non-frozen = 1 span trong flex → appearance giữ nguyên). Gotcha mới đáng nhớ: className header LẶP 2 chỗ (`:1350` budget + `:1931` winners) → Edit anchor PHẢI kèm text visible "Tổng hợp ngân sách trình ký" mới unique. Hash sau sửa `5534addb` ×2 = mirror giữ; npm build ×2 PASS. Tag `[s133, budgetfrozen-badge, anchor-by-visible-text]`
|
||||
|
||||
@ -8,6 +8,7 @@ Read-only INTERNAL audit SOLUTION_ERP. Tools: Read/Grep/Glob/Bash + 5 RAG MCP. O
|
||||
- ❌ NOT: external docs/CVE/lib → investigator-api · write → implementer · test → test-specialist · architecture decision → em main
|
||||
|
||||
## 📌 Recent invest (1-line digest; full detail → archive/runs/git)
|
||||
- **S153 (07-26) ctx soft-memory spec [fable-real]:** thư `0df10df4` sàn-7 → spec 9-task/24-check (`runs/2026-07-26-S153-ctx-adopt/sub-fable-invest-S153.md`). Findings đắt: SE **0 content-ts-reader sống** (session_ctx.py = git-ts+mtime; C10 tự khai thiếu nguồn LATENESS) ⇒ rào-2 canonical `_TS_KEY_RE` đặt session_ctx.py, máy-7-phép = EXTEND python (tái dụng `_SECRET_RES` 1-nguồn) KHÔNG .ps1 mới (2-sự-thật); `secrets_sweep` rglob TRỌN session-dir ⇒ `_mind` tự vào lưới @snapshot §3; `_mind` mới-nhất-ở-TRÊN ⟂ `_context` FLOW ở-CUỐI (bẫy chép-khuôn); (36)(b) máy-$0/pause + vai @2-bookend ⇒ O-1 carve-out KHỎI CẦN (pause §1 NGỪNG-spawn giữ nguyên); C11(b) filter `sub-*.md`+`^sub-<role>[-.]` ⇒ đặt tên `sub-ctx-audit-*` lọt lưới ngay (kẽ trio `harness-*-return` đã queue #8 fix); roster 21 > hmw_width 20 = owner-note; (35)-(38) vết OWNER-DELEGATED khuôn `hmw_width._ratified_by`. Tag `[s153, ctx-mind-spec, ts-reader-absent, one-source-regex]`
|
||||
- **S148 (07-23) PE tree DUP project by-space:** `FLOCK 01`/`FLOCK01` = **path-A TWO real Project rows** diff-by-space. Tree groups on `p.projectId` GUID (`PurchaseEvaluationsListPage.tsx:192-197`, display projectCode); PE→Project FK `ProjectId` (`PurchaseEvaluation.cs:15`) JOIN-resolved (`PeFeatures.cs:579/:647`) — NO denorm string. CRUD zero-trim (`ProjectFeatures.cs:80` validator, `:95/:138` exact `Code==` dupe-check). Both seeds exact-Code key emit ONLY no-space: `SeedRealMasterDataAsync:2776` (UNGATED :128) + `SeedDemoMasterDataAsync:2681` (gated :117 OFF-prod). Space=legacy/manual. Blast=3 tables ProjectId (Contracts/PeWorkItemBudgets/PurchaseEvaluations); only `PeWorkItemBudgets` UNIQUE(ProjectId,WorkItemId) filtered [IsDeleted]=0 (`PeWorkItemBudgetConfiguration.cs:27`). Direction: KEEP no-space (in seed→idempotent), RETIRE space (not-in-seed); soft-del survivor→seed RE-CREATES (#75/#76). Dev only FLOCK 01 pair (FLOCK03/CAL01 space-twins prod-only); prod UNVERIFIED (SSH dies on SQL-client, S134). Tag `[s148, pe-tree-dup-project-by-space, path-A-two-rows, no-normalize-crud]`
|
||||
- **S147 (07-23) PE attach TraLai edit-block:** FE-ONLY block, BE zero phase-guard (`PurchaseEvaluationsController.cs:15` class `[Authorize]` only; handlers check exists only `PurchaseEvaluationAttachmentFeatures.cs:66/:160`). Gate = raw `readOnly` PROP not phase (`GeneralAttachmentsSection` :3555/:3577 hide-when-readOnly); List detail HARDCODE `readOnly=true` (:574/:669) ⇒ TraLai loại khỏi SCREEN không khỏi editable-SET (workspace `PeListPanel.tsx:88` isEditablePhase GỒM TraLai). fe-admin MIRROR. BE no-guard CỐ Ý (S78). Fix FE: `attachEditable=isDrafter&&isEditablePhase`. Tag `[s147, pe-attach-tralai, fe-only-screen-gate]`
|
||||
- **S141 (07-20) adap đợt-9/10 5-lane [fable-clone-ensemble, 5/5 clean]:** (ii)-nới-có-vết đủ đóng dangling-head (3/3 squash-benign, `.session-counter.json`); tick-head=wal-commit. byte-safe⟂tolerant-EXTRACTION 2-lỗ tách → pin regex `\"?([0-9a-fA-F]{8,64})\"?`. Roster-count 3-tầng (prose/glob/pointer). refine⟂lead-omission = discriminator WHOSE-memory. Detail → `runs/…S141…`.
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
# Lead-Omission-Auditor Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) 2 LƯỢT hình-B — vòng V2 `[lead seed on-behalf @closeout M9; nguồn = sub-file đĩa]`:** @open **3 FLAG** — FLAG-1 `gap-carry-dropped` MED-HIGH (**2 khối NEXT-em cùng đánh số ①②③ song song** HANDOFF:8 @S152 vs :13 kỳ-S151; khối MỚI không nuốt mục MỞ ④⑤⑦ của khối CŨ; mục ⑦ owner-#32 "dựng máy per-item-L1-presence" = 0 hit 5 bề mặt) · FLAG-2 `gap-decision-sunk` MED-HIGH (`trio-synthesis.md:13` ra lệnh "H7 → ghi HANDOFF"; H7 = 0 hit, `convention-only` = 0 hit — **đòn bất-đối-xứng**: H6 cùng dòng cùng mệnh-lệnh ĐÃ landed 1 hit ⇒ loại được bào chữa "cả khối bị bỏ", anh chưa từng được hỏi) · FLAG-3 `gap-underfill` MED **fire lần đầu** (target 210K owner-set @S115 có nghĩa-vụ "em-main manual pour from source_order" nhưng `grep source_order|pour` trên 3 command = 0 ⇒ **không tồn tại bước rót**; khai cận-dưới trung thực: 0-hit là cận-dưới vì rót không để lại artifact).
|
||||
**honest-zero có giá:** `gap-owner-specifics` = 0 — (30)(31)(32) codified 3/3 giữ trọn specifics; bảng owner-gated O-1…O-7 = **0 khoản câm** ⇒ **tự BÁC 2 FLAG cũ của mình** (FLAG-1@S148 + FLAG-3@S150). Tự BÁC thêm FLAG-2 HIGH @S150 (`_frozen_until_owner` vắng là ĐÚNG — owner đóng (30) frozen=False).
|
||||
**@close datum riêng:** đo lúc closeout đang mở ⇒ sổ bền TRẮNG là **vô-nghĩa để FLAG**; khuôn đúng = *"cái gì sống DUY-NHẤT ở nơi sắp bị xoá (WAL §6.4 reset) mà không bước nghi-thức nào gánh"* — mirror khuôn "danh-sách sẽ-bốc-hơi" @S150.
|
||||
Tag `[s153, 3-flag-open, 2-khoi-next-em-song-song, don-bat-doi-xung-h6-h7, gap-underfill-fire-lan-dau, honest-zero-tu-bac-3-flag-cu]`
|
||||
|
||||
> 🔄 **RENAME @S149 (2026-07-24, anh ratify):** vai này TRƯỚC ĐÂY tên `lead-omission-auditor` — đổi `lead-gap-auditor` đồng-bộ sister (AI_INFRA/VIPIX). Cùng vai cùng contract; nội-dung diary đã cập-nhật theo tên mới, artifact lịch-sử trong `runs/**`/counter-history giữ tên cũ làm vết. Spawn tên mới chỉ sống SAU restart (no-hot-reload).
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT). Update qua EM-MAIN VERIFY→APPEND (vai = propose-only, RETURN-only — KHÔNG tự ghi file này). Tiered Memory v1: L1 HOT cap ~17KB · entry ≤1.5K chars (#53).
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
# Lead-View-Auditor Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) 2 LƯỢT hình-B (open + close) — vòng V2 `[lead seed on-behalf @closeout M9; nguồn = sub-file đĩa + ring2 verdict]`:** @open **5 FLAG** — FLAG-1 `view-residual-asym` MED (STATUS:454 khai 3 derived-cite `:3/:37/:113`, đo lại **3/3 sai dòng**, đúng là `:5/:48/:315`) · FLAG-2 `view-stale-header` LOW (:439 "mốc gần nhất S151" trong khi :457 re-stamp @S152; `git show c2d01f0` 3 hunk, 0 chạm :439) · FLAG-3 `view-stale-count` LOW (HANDOFF carry-age 12/9/7 vs máy 13/10/8 — lệch **+1 đều 3**, nguồn = chính đoạn carry vừa append ⇒ **self-referential count**) · **FLAG-4 `view-stale-status` HIGH** (STATUS:454 còn khai trio "consent-gated + CHƯA spawn-probe" trong khi owner (32) đã AUTO **và** chính `:466` cùng file nói ngược — bác được không cần ra ngoài file) · FLAG-5 `view-stale-status` MED (H24 nhịp-`{6/15/3}` vs hình-B vô-điều-kiện; đối-chứng hành-vi: lượt này chạy @counter 27 với light 1/6 chưa tới hạn).
|
||||
**ring2 chấm 8/8 ĐẠT** + **thách-CLEAN bắt M-1 MISS THẬT của mình**: persona `lead-stale-auditor.md:51-54` còn dạy "KHÔNG chạy mỗi phiên / thuần cadence" — hình-B đã vô-điều-kiện từ S149, và `398d343` chính đợt land hình-B mở file sửa mà để nguyên câu sai. 🔴 **Bài:** mình bắt ĐÚNG class đó ở STATUS (FLAG-5) nhưng **sót chính persona mình** ⇒ điểm mù **tự-quy-chiếu**; `.claude/agents/` NẰM TRONG tập-đo (đã dùng `agents/README`), chỉ 2 file persona bị bỏ ⇒ lần sau grep tập-đo PHẢI gồm persona của chính mình.
|
||||
Tag `[s153, 5-flag-open, flag4-high-tu-mau-thuan-cung-file, self-referential-count, m1-diem-mu-tu-quy-chieu]`
|
||||
|
||||
> 🔄 **RENAME @S149 (2026-07-24, anh ratify):** vai này TRƯỚC ĐÂY tên `lead-view-auditor` — đổi `lead-stale-auditor` đồng-bộ sister (AI_INFRA/VIPIX). Cùng vai cùng contract; nội-dung diary đã cập-nhật theo tên mới, artifact lịch-sử trong `runs/**`/counter-history giữ tên cũ làm vết. Spawn tên mới chỉ sống SAU restart (no-hot-reload).
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT). Update qua EM-MAIN VERIFY→APPEND (vai = propose-only, RETURN-only — KHÔNG tự ghi file này). Tiered Memory v1: L1 HOT cap ~17KB · entry ≤1.5K chars (#53).
|
||||
|
||||
@ -5,13 +5,27 @@
|
||||
"_last_sleep_at_note": "Harness-10b sleep-recovery (S72): timestamp lan cuoi chay /sleep-recovery-memory-l2. null = chua tung. session-start §2.1.2 + session-end §L.b(c) doc field nay -> INFORM goi-y nen L2 neu null hoac today-last_sleep_at>=7 ngay. Lead=single-writer (chi command sleep set field nay).",
|
||||
"session_ctx_kb": 64,
|
||||
"_session_ctx_kb_owner_set": "🔴 OWNER-SET TUONG-MINH @S146 2026-07-22 — anh chot '1 -> tuong minh' sau khi lead surface DAY DU 2 ly-do phan-bien (K6.2 muon-so-chua-do + H18 ghost-wire). Quyet-dinh cua owner co concern trong tam nhin => THUC THI, khong hoi lai. Don vi = KB; code doc PHAI nhan 1024 (khop manifest hub 101e69d6 'session_ctx_kb: 64'). Nguon so 64 = manifest hub, KHONG phai SE tu do.",
|
||||
"_session_ctx_kb_honest_caveat": "🔴 KHAI THAT, DUNG doc thanh 'da wire': tinh den S146 van la GHOST-WIRE (H18 class-2 defined-but-unread) — do @S146: 0 script doc khoa nay; hit duy-nhat trong scripts/ la COMMENT o nhip-no-probe.ps1:42. Doi chung song: pull_warn_days CO reader that (nhip-no-probe.ps1:190). => Dat so nay KHONG tu-dong tao hanh-vi nao; no la CHOT-SO-TRUOC cho phan wire session-model sau. Ai wire sau PHAI: (a) doc key nay thay vi hardcode 64, (b) nhan 1024, (c) go dong nay khi da co reader that. CAM claim 'session_ctx_kb da hieu-luc' khi chua co reader.",
|
||||
"_session_ctx_kb_reader": "🔄 GHOST-WIRE DONG @S153 2026-07-26 (adopt 0df10df4 T7): reader THAT dau tien = scripts/session_ctx.py mind-check phep-phu-8 — doc khoa nay LIVE, nhan 1024, do _context-s-<N>.md, CO khi vuot (verify acceptance-d @S153: output in 'aux tran _context ... session_ctx_kb'). Lam dung 3 dieu caveat cu tu dan {(a) doc khoa khong hardcode (b) x1024 (c) go dong caveat khi co reader}. 🧊 Lineage: caveat H18 class-2 defined-but-unread song S146→S153 (do @S146 0-reader, hit duy nhat = comment nhip-no-probe.ps1:42; doi chung pull_warn_days co reader that :190) — go dung luc co reader, khong som hon.",
|
||||
"mind_ctx_kb": 32,
|
||||
"_mind_ctx_kb_set": "🔴 OWNER-DELEGATED → ENGINE-PROPOSED → LEAD-DECIDED @S153 2026-07-26 (adopt thu 0df10df4 khoan (35); lenh pipeline anh 26-07 'fable-real invest → spec → hmw xu ly' = UY QUYEN — KHONG PHAI owner chot so; anh veto 1 edit thi doi — khuon hmw_width._ratified_by). Don vi KB, reader x1024 = scripts/session_ctx.py mind-check phep-7 (fail-loud exit-3 khi khoa vang — CAM default, khuon H24-2). Nguon so 32 = hub O-4 (hub tu khai 'so chu dat, khong rut tu du lieu'); SE cung nac khai: file _mind dien hinh <10KB (p=1-3 pause/phien-logic, quan sat S147-S152) => 32 = >=3x headroom; re-tune sau dogfood T9 khi co so do that.",
|
||||
"tiep_reload": {
|
||||
"_note": "🔄 @S153 adopt 0df10df4 khoan (37) RESOLVED (b) — nap-lai NEN RUT-GON mac dinh @/tiep (OWNER-DELEGATED cung vet _mind_ctx_kb_set). Nen-full SE do tuoi @S153 = 596.316B ~ [149.079..198.772] tok (instrument-backfill S153) — nang hon nen hub (439.328B ~ 110K tok) 1.36x, nuot tron rang mem ~150K/cua cua hub-owner neu full => rut gon ~ 40-60K tok (input one-shot cache-duoc). Reader = nghi-thuc /tiep (AI doc danh sach nay qua tiep.md §3-bis TRO KHOA — B1 lenh KHONG chep danh sach); KHAI THANG: chua co script-consumer — KHAC class ghost-wire vi hanh-vi tieu thu moi luot /tiep + dogfood T9 do that. Pham-vi tung muc khoanh ngay trong sources (khuon hub 'do theo pham-vi tung muc da khoanh trong cau-hinh').",
|
||||
"mode": "rut-gon",
|
||||
"sources": [
|
||||
"docs/STATUS.md :: dong CURRENT + bang CURRENT STATE (KHONG ca file)",
|
||||
"docs/HANDOFF.md :: segment Last-updated MOI NHAT (KHONG ca file)",
|
||||
".claude/WAL.md :: tron (<=40 dong by-design)",
|
||||
".claude/sessions/session-<N>/_mind-s-<N>.md :: tron (doc TU TREN XUONG)",
|
||||
".claude/sessions/session-<N>/_context-s-<N>.md :: tron"
|
||||
]
|
||||
},
|
||||
"hmw_width": {
|
||||
"_note": "O-7 (adap dot-11, khoan owner-gated #19). CANONICAL cua tran WIDTH cho hmw.js fan-out. Co-che = LOUD-skip: vuot tran thi CHAY `cap` lane DAU, BO cac lane CUOI, in 4 dong 🔴 (KHONG throw, KHONG lang-thinh). hmw.js giu `const WIDTH_CAP` HARDCODE = MIRROR cua khoa nay, KHONG doc runtime — vi sandbox workflow no-fs (hmw.js:5). Drift giua 2 noi => detector bat (xem _drift_check).",
|
||||
"cap": 20,
|
||||
"mechanism": "loud-skip",
|
||||
"ratified": "2026-07-24",
|
||||
"_ratified_by": "🔴 OWNER-DELEGATED -> LEAD-DECIDED @S149 2026-07-24. KHONG PHAI 'owner chot'. Chuoi su-kien chinh xac: lead trinh anh 4 cau (1 factual + 3 owner-SO/owner-LUAT) -> anh tra loi DUNG hai chu 'Tra loi 4 cau' = UY QUYEN cho lead quyet -> lead quyet + ghi vet nay. Uy-quyen la mot quyet-dinh HOP LE cua owner, nhung no KHAC voi owner tu chon tung so. 🔴 GHI PHAN BIET NAY LA BAT BUOC: dung phien nay lead vua va mot bug o hmw.js:116/:120 noi code tu nang ADOPT-theo-floor thanh 'owner chot O-7 2026-07-22' (0 vet tren 5 be-mat owner). Neu ngay sau do lead ghi 'owner chot' cho chinh khoan ay thi la tai pham trong 1 luot. Anh VETO 1 dong bat cu luc nao thi doi.",
|
||||
"_roster_note_S153": "🔄 ADDITIVE @S153 2026-07-26 (KHONG sua chu nao cua _why_20_not_16 — khoi ly-do da ratify 2026-07-24, chi them cau): roster nay = 23 (.claude/agents/*.md tru README = 23; VALID_ROLES = 23 — dem PHAN-TU sau khi strip comment, vi dau ']' trong comment hmw.js:39 cat regex naive thanh 18). Cap VAN = 20 ⇒ full-roster-sweep LOUD-skip 3 lane CUOI (khong phai vai co-dinh — theo thu-tu taskList). So cap = QUYEN OWNER (O-7); cau hoi (40) dang treo o HANDOFF. Mirror hmw.js WIDTH_CAP = 20 KHOP canonical ⇒ detector C9 IM dung, 0 mirror-drift. Ai nang cap phai doi DONG THOI 2 noi (hmw.js:153 mirror + khoa nay).",
|
||||
"_why_20_not_16": "So CU = 16 (gia tri co san tu ban soft-notice, chua ai ratify). Doi len 20 vi: (a) tran nay KHONG phai de chan concurrency — engine da cap min(16, cpu-2), >16 chi XEP HANG; no chan DOT TOKEN NHAM; (b) sweep TOAN-ROSTER la use-case DA CHAY THAT (S125/S126 chay 14/14 thoi roster 14); roster nay 20 (VALID_ROLES dem tay = 20; .claude/agents/*.md 21 file - README = 20) => cap 16 cat 4 lane, ep chia 2 dot vo co; (c) 20 van la TRAN CUNG chong runaway. 🔴 KHAI THAT rui ro: 8 lane @S149 ton ~1,06M token => 20 lane uoc ~2,5M. Tran cao hon = rui ro dot cao hon; do la danh doi CO Y, khong phai bo qua.",
|
||||
"_why_not_dynamic": "🔴 DA CAN NHAC ROI BAC: 'cap dong = VALID_ROLES.length'. Bac vi so se TROI theo moi lan sua roster => khong con diem ky, tuc DE-OWNER chinh con so ma O-7 sinh ra de owner cam. Engine (/fable-real) neu dung canh bao nay; lead dong y. Roster lon them => owner (hoac uy-quyen) nang tay + ghi vet, KHONG de may tu noi.",
|
||||
"_drift_check": "✅ SONG @S149 (K8 DONE cung phien — reviewer W2 bat note nay stale 'CHUA CO' sau khi C9 da land, va lai): detector C9 `hmw WIDTH mirror-drift` tai scripts/governance-detectors.ps1 (INFORM-only, khong vao TOTAL), regex `const WIDTH_CAP = (\\d+)` vs khoa nay. Fault-inject 4 chieu tren cay tam @S149: khop=>IM · drift 20!=21=>FLAG · mirror MAT HAN=>FLAG (vang != sach) · canonical mat=>FLAG. Ca-4 luot dau HONG (python path /tmp + json chua bi sua => in [ok] nhu that) — chay lai path Windows + assert tien-de roi moi tin.",
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
# MEMORY — ring1-audit (KIỂM vòng-1: tooling/harvest)
|
||||
|
||||
- **S153 (07-26) KIỂM vòng V1 (tooling+harvest) `[lead seed on-behalf @closeout M9; nguồn = sub-ring1-S153.md 22.992B]`:** **28 ĐẠT / 4 TRƯỢT-rìa / 1 KHÔNG-CHẤM trên 33 claim** · falsify 7 phép (4 HELD / 3 BROKE — **1 BROKE vào CHÍNH MÌNH**: `grep -c X f || echo 0` in "0" **và** exit 1 ⇒ đếm nhầm 20/20, suýt tố oan H2 bằng số rác của mình) · tái-dựng 11 số khớp / 1 lệch (đổi nguồn `git ls-files` · đổi engine python↔perl · đổi parse json↔grep · **so TẬP thay so SỐ**).
|
||||
**4 TRƯỢT đều lỗi RÌA, 0 lỗi ở số load-bearing:** H1-15 MED (F-6 **under-count** — dump 18 key thấy `code-review@`+`feature-dev@` cũng `true` dưới cùng heading ⇒ phá claim mà flag NẶNG hơn) · **H2-11 MED BROKE** (baseline S154 "16 + hit của file NÀY" — file H2 có **0 raw U+FFFD**, dùng ASCII `<FFFD>` ×7 ⇒ kỳ sau đọc 16/10 thành SỤT rồi truy **file phantom**; đúng bẫy m#20 mà H2 vừa đặt) · H1-14 LOW (neo `SKILL.md:122` → chuỗi thật ở `:121`; mtime chứng lệch-thật không time-drift) · H2-10 LOW (phân-hoạch 11+5=16 ≠ 20 role-dir; minh-oan: 11 ĐÚNG dưới vị-từ mtime H2 tự khai ⇒ kết-luận không đổi).
|
||||
**Thách-CLEAN 3 mặt — 2 chịu, 1 THỦNG:** ef-core "fresh" THẬT (bảng liên-tục 12..67, 0 lỗ) · Placement 0-stray chịu **3/3 lens** ⇒ số 0 CÓ RĂNG · corruption 16/10 chịu (python≠perl trùng khít) **nhưng THỦNG ở mệnh-đề DỰ-BÁO** ⇒ **ô 🟢 vẫn thủng được ở lời-hứa tương-lai**.
|
||||
Tag `[s153, 28d-4t-33claim, broke-vao-chinh-minh-grep-c, h2-11-baseline-phantom, thach-clean-thung-o-du-bao]`
|
||||
|
||||
> Vai KIỂM độc-lập vòng-đo H1 (`tooling-auditor`) + H2 (`harvest-curator`) — C4/C4b, land S145, rename @S149 (cũ: `tooling-harvest-audit`). Read-only, propose-only, AUTO fire SAU khi H1+H2 chốt @session-end §L.b(g-bis). Fail-safe: H1/H2 không chạy ⇒ NO-OP im-lặng, CẤM ĐẠT-ảo. no-self-exempt: ≠ H1/H2.
|
||||
|
||||
## Seed (2026-07-25 S150 — lead ghi on-behalf, M9/B3)
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
# ring2-audit Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) KIỂM vòng V2 (soi-lead H24) `[lead seed on-behalf @closeout M9; nguồn = sub-ring2-S153.md]`:** **8/8 FLAG ĐẠT / 0 TRƯỢT / 0 KHÔNG-CHẤM + 10 phép phụ** · falsify 6 (5 HELD, **1 BROKE là nghi-vấn của chính mình**: nghi `h24_cadence` là pointer treo → probe đường khác thấy key có thật top-level `:146-151` = 6/15/3 ⇒ con-đo **kiềm chế ĐÚNG**, ghi VERIFIED-CLEAN thay báo-động-giả).
|
||||
**Tái-dựng MẠNH hơn endpoint:** kéo bản TRƯỚC bằng `git show HEAD:.session-counter.json` rồi so **delta từng key** — 7/7 class fired = **+1 chính xác**, 4/4 non-fired = **0**, 11 key cả 2 phía, mọi value `int` (bất-biến `2f39a7e` còn sống), `light_at_counter` 26→27, `signal_session` S152→S153. Ngữ-nghĩa đúng: `view-stale-status` fire 2 FLAG nhưng counter chỉ +1 (đếm **vòng-đo**, không đếm flag).
|
||||
🔴 **THÁCH-CLEAN bắt M-1 MISS THẬT (giá trị nhất lượt):** `lead-stale-auditor.md:51-54` tiêu-đề "## Nhịp — mày KHÔNG chạy mỗi phiên" + mô-tả bắn thuần cadence, trong khi `session-end.md:114/116` = hình-B VÔ-ĐIỀU-KIỆN + `light_every` hạ stats-only; cặp đã chạy S150-S153 liên tiếp. **Khẳng-định phủ-định SAI**, không phải bỏ trống. Bất-đối-xứng: commit chạm persona gần nhất = `398d343` "bookend lượt đầu (hình B)" ⇒ **chính đợt land hình-B mở file mà để nguyên câu sai**; 0 marker 🧊 ⇒ không phải đóng-băng-chủ-đích. Hại cụ-thể: persona auto-inject ⇒ vai đọc đúng chữ sẽ tự tính "chưa tới lượt tao" — sai ngay tại bookend, load-bearing hơn STATUS:454.
|
||||
**Khuôn slot (33) có RĂNG cả 2 vai:** `grep -c '^## FLAG-'` = 5==5 · 3==3 khớp END TOTAL ⇒ rủi-ro pin-bản-cắt 4-A (tự nêu @S152) nay đã chặn.
|
||||
Tag `[s153, 8-8-dat, delta-counter-11-key, m1-mien-tru-persona-cua-vai-do, falsify-broke-vao-nghi-van-cua-minh]`
|
||||
|
||||
> 🔄 **RENAME @S149 (2026-07-24, anh ratify):** vai này TRƯỚC ĐÂY tên `h24-audit` — đổi `ring2-audit` đồng-bộ sister (AI_INFRA/VIPIX). Cùng vai cùng contract; nội-dung diary đã cập-nhật theo tên mới, artifact lịch-sử trong `runs/**`/counter-history giữ tên cũ làm vết. Spawn tên mới chỉ sống SAU restart (no-hot-reload).
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT). Update qua EM-MAIN VERIFY→APPEND (vai = propose-only, RETURN-only — KHÔNG tự ghi file này). Tiered Memory v1: L1 HOT cap ~17KB · entry ≤1.5K chars (#53).
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# Test-Specialist Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) T4 ctx-adopt FAULT-INJECT máy `mind-check` #8-#17+#21 [run 2026-07-26-S153-ctx-adopt · lane trước đứt sau #7, file đĩa nguyên → tiếp được] `[engine: opus-5]`:** **18/18 PASS 0 FAIL**. KHÔNG phải test C# (**baseline 509 KHÔNG đổi**) — đối tượng = `scripts/session_ctx.py mind-check`, mọi mutation trong cây tạm qua seam `--root`, repo read-only. Bắt **1 GAP THẬT**: ở closed-mode **XOÁ con-trỏ → cờ/exit 0** còn **GIỮ con-trỏ đang-chờ trung thực → TRƯỢT/exit 1** ⇒ đường-rẻ-nhất-để-xanh là đường SAI (chữ luật cấm, gradient thưởng) → REPORT em main, KHÔNG tự sửa. **Bài học mới quan trọng nhất:** fixture `draft-ts` MALFORMED ra exit 0 — `inject_A` neo `## MIND-1` sau khi `renum(...,2)` đã đổi heading ⇒ `str.find`=-1 ⇒ chèn GIỮA heading ⇒ `ts:` không ở đầu dòng ⇒ máy ĐÚNG mà vẫn xanh. **Fixture-hỏng cho-xanh trông Y HỆT máy-đúng cho-xanh** ⇒ phải soi RUỘT fixture (`cat -A`/`repr` từng dòng), KHÔNG chỉ đọc exit code. 2 kỹ thuật xài lại: (i) **cặp CÙNG-RUỘT khác 1 biến** — cap=32 vs cap=1 trên cùng tệp = chứng đọc-config-LIVE; `_end` giả `_pause=9` vs không = chứng nguồn-đếm-là-ĐĨA, dùng `diff` 2 output để chứng dòng đo BYTE-IDENTICAL; (ii) **đo wall-clock phải gồm nhánh ĐẮT** — lệnh literal đi nhánh early-exit (repo chưa có `_mind`) = tự đo nhánh rẻ rồi gọi là chi phí thật; đo 55-64ms/lượt vs ước 140-300ms ⇒ lệch 2.2-5.4×, giao lead điền lại. Tag `[s153, t4-fault-inject, mind-check, fixture-bug-vacuous-pass, cung-ruot-1-bien]`
|
||||
|
||||
- **S134 (07-17) PE lũy-kế TẠM TÍNH TEST-C [wf_97d6a582-b7e · return sạch 0-garble] `[engine: opus-worker]`:** +8 `PePendingAccumulationTests.cs` C1-C8 (file MỚI, mirror seed PeBudgetFreezeTests :277-336): C1 ChoDuyet+winner→delta2+PriorPes · C2 TuChoi/DaDuyet loại sạch · C3 nháp list-only/TraLai delta1 · C4 window CreatedAt · C5 delta âm signed · **C6 complementary-no-double-count: gọi CẢ ComputeAsync + ComputePendingAsync cùng seed, assert EXACT-NUMBERS 2 phía (PrevSelected 90tr/1 bất động ⟂ PendingSelected 50tr/1)** · C7 frozen→0/null qua query handler · C8 D4 changelog positive+contrast (filter `ContextNote.Contains("[S134 pending-prior]")` #48). Full **528/0** (45D+483I, +8). Learned: (1) **direct-call accumulator = synthetic curPeId + CreatedAt muộn, KHÔNG cần row phiếu-đang-xét** (chỉ filter Id!=/CreatedAt<); (2) regression "bất động" mạnh nhất = C6-style exact-numbers 2 hàm cùng seed; (3) FluentAssertions `ContainInOrder(params T[])` + because-string overload-clash khi T=Guid → bọc `new[]{...}` trước. Surprise: D4 no-SaveChanges-in-helper → row chỉ persist sau TransitionAsync. Tag `[s134, pependingaccumulation, c6-exact-numbers-complementary, 8-test]`
|
||||
|
||||
- **S133 INV-C T1-T9 [wf_75c6bfd3-754 · #53 return-fail lần 3 → disk + lead tự chạy suite; entry on-behalf]:** +9 test vào PeBudgetFreezeTests (`:426` T1 đủ-11-cột · `:480` T2 CCM-threshold · `:524` T3 all-steps · `:555` T4 V1-legacy assert KHÔNG-ApprovedPrice · `:638` T5 guard CCM+Admin Conflict + ChoDuyet-allow · `:687` T6 AdjustBudget DaDuyet+TuChoi · `:730` T7 live-vs-frozen flags/editability · `:783` T8 null-safe no-WorkItem + no-pair · `:821` T9 overwrite + SnapshotAt refresh). FULL suite lead-verified exit-0: **Domain 45 + Infra 474 = 519, 0 fail** (464+10 khớp). ⚠️ Lesson mới: INV-C **ghi đè** `sub-test-specialist-0.md` của INV-A — cùng role + cùng task-index qua 2 invocation chung run-folder = sub-file collision; INV-A content sống nhờ journal + diary. Multi-invocation cùng run → cần label/index phân biệt (báo lead khi gặp lại). Tag `[s133, t1-t9, subfile-collision-multi-invocation]`
|
||||
@ -61,16 +63,15 @@ Test theo CODE (single source truth), document mismatch header comment + report.
|
||||
|
||||
## 📅 Recent activity (one-line FIFO — verbose in [archive/baseline-history.md](archive/baseline-history.md))
|
||||
|
||||
- **S118b (2026-07-14) ReportsController company-wide-report authz REGRESSION (test-after SECURITY — reviewer catch) — 505→509 PASS (+4 Infra), no-red, NO prod bug:** EXTEND `Api/AuthorizePolicyRegressionTests.cs` (Pattern 10 reflection, +4 [Fact] → file 15→19). Fix S118: 2 endpoint company-wide `Dashboard`+`ExportContracts` (lộ tài chính HĐ toàn cty: tổng giá trị, top NCC/dự án, xu-hướng-12-tháng, export-Excel) NAY gate `[Authorize(Policy="Reports.Read")]` (chỉ Admin, khớp S92); `MyDashboard` CỐ Ý giữ mở (chỉ class-level `[Authorize]` trần, scope currentUser). Trước: cả controller class-level `[Authorize]` trần → mọi user đăng nhập gọi được = lộ tài chính. **T1** class-level `[Authorize]` Policy=null+Roles=null (bare — nếu hardcode Policy sẽ khóa my-dashboard). **T2/T3** Dashboard+ExportContracts action-Policy==`Reports.Read` (gỡ→NotBeNull-fail = tái-lộ toàn cty). **T4** MyDashboard `(attr?.Policy).Should().BeNull()` — cho phép bare `[Authorize]` vô-hại NHƯNG chặn mọi Policy (thêm policy→khóa dashboard cá-nhân role không-Admin). csproj ĐÃ ref Api (line 25, từ S45) — KHÔNG vướng reference. KHÔNG touch prod.
|
||||
- **S118 (2026-07-14) Procurement master-access seeder SCOPE-ISOLATION regression (test-after SECURITY — anh Kiệt FDC) — 501→505 PASS (+4 Infra), no-red, NO prod bug:** new `ProcurementMasterAccessSeedTests.cs` (4 [Fact]) guard seeder MỚI `SeedProcurementMasterAccessAsync` (private static, DbInitializer) — NGOẠI-LỆ role Procurement mở lại Danh mục SAU S92 revoke ("chỉ Admin thấy"). Chain thật: Revoke→SeedProcurement. **T1 upgrade-path** Procurement sau revoke→seed đúng ma trận (Suppliers R+C+U D=false + 8 read-only chỉ R). **T2 ⭐SCOPE-ISOLATION (core)** DeptManager đứng RIÊNG (KHÔNG kèm Procurement): pre-grant→revoke→seed → 9 key VẪN all-false (row tồn tại giữ vết) = grant KHÔNG rò role khác; +CONTRAST assert Procurement THẬT được nâng (chống vacuous-pass). **T3 insert-path** DB mới no-revoke → INSERT 9 row, Delete=false + count==9. **T4 idempotent** seed ×2 → bất biến + count==9 no-dup + role khác vẫn ẩn. Reflection harness MIRROR `AdminOnlyModulesRevokeTests` (NonPublic|Static, sig (ApplicationDbContext,RoleManager<Role>,ILogger), FK seed MenuItem→Role→Permission). No user cần (perm role-level). **Reflection KHÔNG vướng — KHÔNG cần đổi visibility.** KHÔNG touch prod.
|
||||
- **S117 (2026-07-14) PE "duyệt theo KHOẢNG" ProMinMax range-price TEST-BEFORE-MERGE (financial-critical) — 495→500 PASS (+5 Infra, file 10→15), no-red, NO prod bug:** feature anh Kiệt: PRO có cả Min&Max → người duyệt cấp cuối chọn CẢ HAI (source="ProMinMax") → `ApprovedPriceAmount=Min`, `ApprovedPriceMaxAmount=Max`. Bất-biến `Max!=null ⟺ Source=="ProMinMax"`. Prod đã land: `ApplyApprovedPriceOnFinalize(...,decimal? maxAmount=null)` +`ValidApprovedPriceSources`+"ProMinMax"; `TransitionAsync`/`ApproveV2Async` +`approvedPriceMaxAmount` (SAU source). 5 new [Fact] qua reachable terminal path (mirror case-1 SeedSingleApproverWorkflow, KHÔNG gọi private): (a) happy Min100/Max130 set cả 2 · (a-boundary) **min==max OK** lock guard `>` vs `>=` (revert→RED) · (b) thiếu Max→Conflict "*phải có cả giá Min và giá Max*" not-finalized · (c) min>max→Conflict "*không được lớn hơn giá Max*" · (d) nguồn ĐƠN+Max→Conflict "*kèm giá Max*" wire-bug-guard. +regression assert `Max==null` vào Theory 3b (4 nguồn đơn). **⚠️ Gotcha (self-inflicted-avoided):** prod method 5-param nay → `InvokeApply` reflection helper phải pass 5 args (`{...,maxAmount}`); optional param KHÔNG auto-bind qua `MethodInfo.Invoke` → nếu giữ 4 args = `TargetParameterCountException` phá unit-test 4/4b/4c. Đã fix helper. KHÔNG touch prod.
|
||||
- **S116 (2026-07-13) PE báo giá SỐ ÂM regression-lock (test-before cho guard R2-revised — critical-algo/financial) — 486→495 PASS (+9 Infra), no-red, NO prod bug:** feature anh Kiệt cho ThanhTien ÂM (phát-sinh-giảm/hoàn tiền NCC = giá THẬT). BE ĐÃ đổi submit-guard `:202-208` `Sum()<=0`→`Count==0`(chưa chọn)/`else All(x==0)`(chưa có giá). 4 nhóm test khớp hành-vi MỚI: **T1** `PeWorkItemBudgetTests` (+1) quote ÂM −20tr KHÔNG chạm PeWorkItemBudget record (FullAmount ngân sách bất biến) NHƯNG CHẢY vào CurrentProposalTotal=−20tr (chứng tách-biệt cột đề-xuất vs ngân-sách, "0 code" kiến-trúc). **T2** `PeMultiWinnerTests` (+2) winnerQuoteTotal=SUM CÓ DẤU khác-winner(+50,−20=30) + cùng-winner-2-dòng(80,−30=50). **T3** `PeSubmitGuardAndBypassTests` (+4, +2 helper `SeedWinnerWithQuotesAsync` params + `BuildV2PeReadyToSubmitWithQuotesAsync`): all-zero[0,0]→BLOCKED "chưa có giá"; pure-neg[−500k]→ChoDuyet; mixed net>0→ChoDuyet; 🔒 **mixed net==0 từng-dòng≠0 [+500k,−500k]→ChoDuyet** = ranh giới phân-biệt All(==0) vs Sum()<=0 (revert→RED). **T4** `PeCcmThresholdFinalizeTests` (+2, +helper 2-signed-quote): NET threshold — [+1.2tỷ,−0.3tỷ]=0.9tỷ<ngưỡng→CCM finalize no-throw + CONTRAST [+1.2tỷ] alone=1.2tỷ≥ngưỡng→Conflict (dòng âm LOAD-BEARING, R-CEO giữ NET). KHÔNG touch prod.
|
||||
- **S113 (2026-07-12) Supplier import v2 dedup + publish-guard TEST-AFTER (critical-algo + security) — 458→477 PASS (+19 Infra), no-red, 🔴 1 BUG-FOUND (REPORTED em-main, NOT fixed):** 2 new files `Services/SupplierImportV2DedupTests.cs` (13) + `Application/SupplierPublishAndListTests.cs` (6). Existing S112 file UNTOUCHED (re-baked ExpectedHeaderTokens=30 \n-token → real tokens khớp → Case9 tự flip LayoutValid=true). **Dedup precedence** existing-MST→existing-Code→batch-MST→batch-Code→New: strip-ws-normalize MST-match · 2-blank-MST=2-insert (blank không index) · same-MST-batch=1-insert+fill-null-skip · **Code-backstop CI** (S112: dedup ở SERVICE OrdinalIgnoreCase, SQLite BINARY KHÔNG bắt "backstop"≈"BACKSTOP" → xanh=chứng không dựa DB) · **MST→A/Code→B = MST-precedence WINS, no silent-clobber** (FillNulls skip Code → A.Code giữ, B untouched). **Publish** `PublishSupplierCommand` (KHÔNG UpdateSupplier #73): gate D2 Publish+blank-Code→Conflict "Cần Mã NCC" · unique-exact→Conflict "đã tồn tại" (⚠️ `x.Code==newCode` DB-collation, SQLite bắt exact-case only — prod SQL CI bắt CI-dup; asymmetry vs import, observation không bug) · unpublish always. ListSuppliers Published t/f/null · GetSupplier DTO.IsPublic. **🔴 BUG:** `NewSupplier` `Code=r.Code!.Trim()` → NRE khi row.Code==NULL (path R4 nháp: parser sinh null ô rỗng + preview classify New no-error → confirm NRE → 500 CẢ batch dbCount=0). Empty ""=OK (T8/T14). Characterization test CHỐT NRE → fix null-safe thì flip NotThrow+draft.
|
||||
- **D4 (2026-07-12) PE sign-off A1 + EDGE-5 + opinion-history TEST-BEFORE-MERGE (critical-algo bug-fix + security) — 450→458 PASS (+8 Infra, 4 updated in-place), no-red, NO prod bug:** BE đổi `ApplyDrafterBypassOnSubmitAsync` sang **A1** trong `PeSubmitGuardAndBypassTests.cs`. **4 updated + RENAMED** (tên cũ misleading): drafter bypass CHỈ cấp NV dưới THUẦN (Order<minOwn); pointer DỪNG tại minOwn (người soạn ký TAY qua ApproveV2Async); KHÔNG auto-sign opinion chính chủ / KHÔNG auto-terminal-on-submit / KHÔNG auto nhảy Bước. minOwn=1 (drafter Cấp1 hoặc non-contiguous Cấp1+3) → bypass RỖNG (opinion=0, AutoApprove=0). **8 new:** A1 happy-path (drafter ký Cấp2 comment THẬT — canned "duyệt tự động" đã GỠ khỏi prod, grep 0-match) · non-contiguous full-manual-chain đúng thứ tự · EDGE-5 ×4 (non-admin Reject từ DaDuyet/TuChoi → Conflict "trạng thái kết thúc"; **Admin + system[actorUserId=null+AutoApprove] MIỄN** → fall-through "không hỗ trợ" chứng minh qua-guard) · opinion-history ×2 (re-sign đè opinion non-empty → đúng 1 Changelog Workflow/Update EntityId=level.Id ContextNote chứa comment cũ; first-sign / đè-rỗng → 0 row, filter theo EntityId==levelId loại được Trả-lại-changelog EntityId=null). Helpers: `ApproveAsync` (approvedPrice khi ký cấp CUỐI terminal — ApplyApprovedPriceOnFinalize Conflict nếu thiếu, isSystem miễn) + `ReturnToDrafterAsync` (AllowReturnToDrafter default TRUE trên Level). Empty-opinion chỉ reachable qua seed-trực-tiếp (normalizedComment placeholder-hoá whitespace).
|
||||
|
||||
- **D3 (2026-07-12) Supplier Excel-import BE (Phase B) TEST-BEFORE-MERGE (CRITICAL-ALGO + case-collation bug-class) — 440→450 PASS (+10 Infra), no-red, NO prod bug:** new `Services/SupplierExcelImportServiceTests.cs` (10 [Fact]). **Case-collation (THE bug):** ConfirmAsync lowercase `truonggiang` vs DB `TRUONGGIANG` → Inserted=0/Updated=1/count=1 (dedup ở SERVICE `OrdinalIgnoreCase`, KHÔNG dựa DB — SQLite fixture BINARY collation KHÔNG bắt CI-dup, prod SQL Server CI thì có → nếu Ordinal = 500 batch); Preview classify Update. **Fill-nulls SAFE** (non-null giữ / null điền). **All-or-nothing** (1 hard-error→Committed=false + DB unchanged). MapType unknown→NhaCungCap+warning · emoji-strip status → DangHoatDong · valid-layout absolute-index parse (LinkGuq RAW backslash) · no-column-drift (col9 empty→col12 vẫn TaxCode) · #REF! literal→null. **Pattern (reuse):** header xlsx dựng từ `ExpectedHeaderTokens` qua REFLECTION (`GetField(NonPublic|Static)`) → valid-layout test tự đồng bộ khi tokens sửa; ClosedXML in-mem `XLWorkbook.AddWorksheet`+`ws.Cell(r,c).Value=string` GIỮ TEXT (0.105 no numeric-coercion → leading-zero safe). **Spec-drift FLAGGED (không phải bug):** `ExpectedHeaderTokens` = BEST-GUESS ≠ 30 real row-4 token → Case 9 dynamic `LayoutValid==(NormalizeJoin(real)==NormalizeJoin(reflected))` robust 2-chiều, hiện LayoutValid=false; close-review sẽ sửa tokens → test tự flip true.
|
||||
- **S97 (2026-07-01) PE EndsBeforeCeo CONFIG→RUNTIME (bug anh Kiệt FDC, spec-change test) — 440 PASS no-red, NET +0 [Fact] (extend in-place):** em-main BE thêm `PurchaseEvaluation.EndedByLevelFinalize` (Mig 60) set true DUY NHẤT nhánh level-finalize `ApproveV2Async`. ListApproved (DaDuyet-only) đọc THẲNG field (`CreateContractFromEvaluationFeatures.cs:196`); List/Inbox ternary `Phase==DaDuyet ? field : subquery`. **Spec-change RED handled:** `PeFinalizeProjectionTests` seed-helper +param `endedByLevelFinalize` → case cũ `peFin` set true; **REPRO case mới `peFinButWentCeo`**: CÙNG wfFin config-có-finalize NHƯNG field=FALSE → EndsBeforeCeo=FALSE (bug: config-true nhưng lên CEO thật). FinalizeStep/LevelName VẪN từ config-subquery (nhãn cấp, không phải cờ). **EF-translate OK** (ListApproved handler no-throw). Service `PeApproverFinalizeTests` +3 assert: #1 finalize→true / #2 advance-CEO→false / #6 opt-out→false (khớp projection repro). No prod bug.
|
||||
- **S92 (2026-06-29) +3 admin-only-modules revoke (test-before-merge SECURITY) — 431→434 PASS, no red:** anh chốt 5 nhóm menu (NHÂN SỰ/VĂN PHÒNG SỐ/CÁ NHÂN/HỢP ĐỒNG/DANH MỤC) CHỈ Admin thấy. Em-main mở rộng `RevokeTemporarilyHiddenModulesAsync` predicate +Contracts/Ct_*/Master/Suppliers/Projects/Departments/Catalog* (cộng dồn S58 Hrm*/Off*/Personal) + TẮT 2 re-grant S65/S69 + narrow `InReviewScope→Pe_*`. `AdminOnlyModulesRevokeTests.cs` (3): NonAdmin-S92Modules-4cờ-false LOAD-BEARING + Admin-untouched + Pe-module-NOT-revoked invariant (root `PurchaseEvaluations` + `Pe_DuyetNcc` không match predicate → giữ user). Reflection harness mirror Office/Hrm seed test. **Gotcha:** OfficeModulePermissionSeedTests + HrmProfilePermissionSeedTests VẪN PASS dù prod đã TẮT 2 call grant — vì test invoke method-CÔ-LẬP qua reflection (private static giữ cho reversibility), KHÔNG chạy SeedAsync chain; thêm 1 dòng header note mỗi file. (ChangePassword S91 10-test ĐÃ merge → trong baseline 431.)
|
||||
- **S118b** +4 ReportsController company-wide authz (Pattern 10 reflection; `Dashboard`+`ExportContracts` gate `Reports.Read`, `MyDashboard` CỐ Ý bare `[Authorize]`) → 509.
|
||||
- **S118** +4 Procurement master-access seeder SCOPE-ISOLATION (grant KHÔNG rò sang role khác + CONTRAST assert chống vacuous-pass) → 505.
|
||||
- **S117** +5 PE ProMinMax duyệt-theo-KHOẢNG (boundary min==max; ⚠️ `MethodInfo.Invoke` KHÔNG auto-bind optional param → helper phải pass đủ 5 args) → 500.
|
||||
- **S116** +9 PE báo giá SỐ ÂM (guard `Sum()<=0`→`All(x==0)`; ranh giới net==0 mà từng-dòng≠0; CCM threshold giữ NET) → 495.
|
||||
- **S113** +19 Supplier import v2 dedup precedence MST→Code (dedup ở SERVICE, không dựa DB-collation) + publish-guard; 🔴 BUG NRE `Code!.Trim()` khi Code==NULL (REPORTED em-main).
|
||||
- **D4** +8 PE sign-off A1 (drafter bypass CHỈ cấp NV dưới THUẦN, pointer dừng tại minOwn) + EDGE-5 terminal-reject + opinion-history changelog.
|
||||
- **D3** +10 Supplier Excel-import case-collation (dedup SERVICE `OrdinalIgnoreCase`; SQLite BINARY KHÔNG bắt CI-dup, prod SQL thì có) + header-xlsx-từ-REFLECTION pattern.
|
||||
- **S97** ±0 PE EndsBeforeCeo CONFIG→RUNTIME spec-change (repro case mới: config-có-finalize NHƯNG field=false = phiếu thật lên CEO).
|
||||
- **S92** +3 admin-only-modules revoke; gotcha: seed-test VẪN PASS dù prod đã TẮT call grant — vì test invoke method CÔ-LẬP qua reflection, không chạy SeedAsync chain.
|
||||
- **S87** +7 PE Mig 59 CCM-budget-period setter authz (`PeCcmBudgetPeriodSetterAuthzTests.cs`, role-gate Admin|CostControl, null=clear gotcha #73). → 402.
|
||||
- **S86** +3 PE drafter-notify-exclusion REGRESSION (bug-fix test-alongside; `PeApproverNotifyExcludesDrafterTests.cs`, RED-proven-via-git-stash, CapturingNotificationService spy).
|
||||
- **S85b** +3 PE UpdateDraft WF-preserve ROOT-FIX (null-safe guard, ApprovalWorkflowId FK Restrict seed-real). **S85** +5 PE urgent DRAFTER-self-unset (isDrafter clear-both).
|
||||
|
||||
@ -6,6 +6,15 @@
|
||||
- activity-s51-s52.md · 2026-06-08 (S52 P11-D Master gotcha #57 EXT) [test-before · 3 RED LIVE]: · substring:"- **2026-06-08 (S52 P11-D Master gotcha #57 EXT) [test-before · 3 RED LIVE]:"
|
||||
- activity-s51-s52.md · 2026-06-08 (S52 P11-E + P11-F WorkflowApps/Attendance test-after · substring:"- **2026-06-08 (S52 P11-E + P11-F WorkflowApps/Attendance test-after"
|
||||
- activity-s51-s52.md · 2026-06-08 (S51 P11-C HMW Wave2 filtered-unique gotcha #57 · substring:"- **2026-06-08 (S51 P11-C HMW Wave2 filtered-unique gotcha #57"
|
||||
- baseline-history.md · S118b — ReportsController company-wide-report authz REGRESSION (test-after SECURITY), +4 -> 509 · substring:"S118b — ReportsController company-wide-report authz REGRESSION (test-a"
|
||||
- baseline-history.md · S118 — Procurement master-access seeder SCOPE-ISOLATION regression (test-after SECURITY), +4 -> 505 · substring:"S118 — Procurement master-access seeder SCOPE-ISOLATION regression (te"
|
||||
- baseline-history.md · S117 — PE ProMinMax duyet-theo-KHOANG range-price (test-before-merge FINANCIAL), +5 -> 500 · substring:"S117 — PE ProMinMax duyet-theo-KHOANG range-price (test-before-merge F"
|
||||
- baseline-history.md · S116 — PE bao gia SO AM regression-lock (test-before guard R2-revised), +9 -> 495 · substring:"S116 — PE bao gia SO AM regression-lock (test-before guard R2-revised)"
|
||||
- baseline-history.md · S113 — Supplier import v2 dedup + publish-guard (test-after critical-algo + security), +19 -> 477 · substring:"S113 — Supplier import v2 dedup + publish-guard (test-after critical-a"
|
||||
- baseline-history.md · D4 — PE sign-off A1 + EDGE-5 + opinion-history (test-before-merge critical-algo), +8 -> 458 · substring:"D4 — PE sign-off A1 + EDGE-5 + opinion-history (test-before-merge crit"
|
||||
- baseline-history.md · D3 — Supplier Excel-import BE Phase B (test-before-merge case-collation bug-class), +10 -> 450 · substring:"D3 — Supplier Excel-import BE Phase B (test-before-merge case-collatio"
|
||||
- baseline-history.md · S97 — PE EndsBeforeCeo CONFIG->RUNTIME (spec-change test), +0 (extend in-place) · substring:"S97 — PE EndsBeforeCeo CONFIG->RUNTIME (spec-change test), +0 (extend "
|
||||
- baseline-history.md · S92 — admin-only-modules revoke (test-before-merge SECURITY), +3 -> 434 · substring:"S92 — admin-only-modules revoke (test-before-merge SECURITY), +3 -> 43"
|
||||
- baseline-history.md · Count progression (one-line chain) · substring:"Count progression (one-line chain)"
|
||||
- baseline-history.md · D2 — PE Mig 58 multi-winner (test-after + EF translation-smoke), +6 → 419 · substring:"D2 — PE Mig 58 multi-winner (test-after + EF translation-smoke), +6 →"
|
||||
- baseline-history.md · S87 — PE Mig 59 CCM-budget-period setter (test-after authz), +7 · substring:"S87 — PE Mig 59 CCM-budget-period setter (test-after authz), +7"
|
||||
|
||||
@ -12,6 +12,33 @@ metadata:
|
||||
## Count progression (one-line chain)
|
||||
254 (S60) → 263 (S61 +22 PeWorkItemBudget, −14 BudgetPolicy Domain drop) → 286 (S67 +23 HRM) → 292 (S69 +6 Office) → 306 (S69b +14 PE) → 334 (S72 +28 PE Mig54) → 339 (S74 +5 CcmNote) → 344 (S76 +5 PRO-split) → 351 (S77 +7 suggested-price NOTE) → 354 (S77b symmetric, superseded) → 366 (S78-S84, MEMORY chưa ghi từng delta) → 371 (S85 +5 urgent drafter-unset) → 374 (S85b +3 UpdateDraft WF-preserve) → 377-395 (S86-S86d) → 402 (S87 +7 CCM-budget-period) → **419 (D2 +6 PE Mig58 multi-winner + translation-smoke)**.
|
||||
|
||||
## S118b — ReportsController company-wide-report authz REGRESSION (test-after SECURITY), +4 -> 509
|
||||
**S118b (2026-07-14) ReportsController company-wide-report authz REGRESSION (test-after SECURITY — reviewer catch) — 505→509 PASS (+4 Infra), no-red, NO prod bug:** EXTEND `Api/AuthorizePolicyRegressionTests.cs` (Pattern 10 reflection, +4 [Fact] → file 15→19). Fix S118: 2 endpoint company-wide `Dashboard`+`ExportContracts` (lộ tài chính HĐ toàn cty: tổng giá trị, top NCC/dự án, xu-hướng-12-tháng, export-Excel) NAY gate `[Authorize(Policy="Reports.Read")]` (chỉ Admin, khớp S92); `MyDashboard` CỐ Ý giữ mở (chỉ class-level `[Authorize]` trần, scope currentUser). Trước: cả controller class-level `[Authorize]` trần → mọi user đăng nhập gọi được = lộ tài chính. **T1** class-level `[Authorize]` Policy=null+Roles=null (bare — nếu hardcode Policy sẽ khóa my-dashboard). **T2/T3** Dashboard+ExportContracts action-Policy==`Reports.Read` (gỡ→NotBeNull-fail = tái-lộ toàn cty). **T4** MyDashboard `(attr?.Policy).Should().BeNull()` — cho phép bare `[Authorize]` vô-hại NHƯNG chặn mọi Policy (thêm policy→khóa dashboard cá-nhân role không-Admin). csproj ĐÃ ref Api (line 25, từ S45) — KHÔNG vướng reference. KHÔNG touch prod.
|
||||
|
||||
## S118 — Procurement master-access seeder SCOPE-ISOLATION regression (test-after SECURITY), +4 -> 505
|
||||
**S118 (2026-07-14) Procurement master-access seeder SCOPE-ISOLATION regression (test-after SECURITY — anh Kiệt FDC) — 501→505 PASS (+4 Infra), no-red, NO prod bug:** new `ProcurementMasterAccessSeedTests.cs` (4 [Fact]) guard seeder MỚI `SeedProcurementMasterAccessAsync` (private static, DbInitializer) — NGOẠI-LỆ role Procurement mở lại Danh mục SAU S92 revoke ("chỉ Admin thấy"). Chain thật: Revoke→SeedProcurement. **T1 upgrade-path** Procurement sau revoke→seed đúng ma trận (Suppliers R+C+U D=false + 8 read-only chỉ R). **T2 ⭐SCOPE-ISOLATION (core)** DeptManager đứng RIÊNG (KHÔNG kèm Procurement): pre-grant→revoke→seed → 9 key VẪN all-false (row tồn tại giữ vết) = grant KHÔNG rò role khác; +CONTRAST assert Procurement THẬT được nâng (chống vacuous-pass). **T3 insert-path** DB mới no-revoke → INSERT 9 row, Delete=false + count==9. **T4 idempotent** seed ×2 → bất biến + count==9 no-dup + role khác vẫn ẩn. Reflection harness MIRROR `AdminOnlyModulesRevokeTests` (NonPublic|Static, sig (ApplicationDbContext,RoleManager<Role>,ILogger), FK seed MenuItem→Role→Permission). No user cần (perm role-level). **Reflection KHÔNG vướng — KHÔNG cần đổi visibility.** KHÔNG touch prod.
|
||||
|
||||
## S117 — PE ProMinMax duyet-theo-KHOANG range-price (test-before-merge FINANCIAL), +5 -> 500
|
||||
**S117 (2026-07-14) PE "duyệt theo KHOẢNG" ProMinMax range-price TEST-BEFORE-MERGE (financial-critical) — 495→500 PASS (+5 Infra, file 10→15), no-red, NO prod bug:** feature anh Kiệt: PRO có cả Min&Max → người duyệt cấp cuối chọn CẢ HAI (source="ProMinMax") → `ApprovedPriceAmount=Min`, `ApprovedPriceMaxAmount=Max`. Bất-biến `Max!=null ⟺ Source=="ProMinMax"`. Prod đã land: `ApplyApprovedPriceOnFinalize(...,decimal? maxAmount=null)` +`ValidApprovedPriceSources`+"ProMinMax"; `TransitionAsync`/`ApproveV2Async` +`approvedPriceMaxAmount` (SAU source). 5 new [Fact] qua reachable terminal path (mirror case-1 SeedSingleApproverWorkflow, KHÔNG gọi private): (a) happy Min100/Max130 set cả 2 · (a-boundary) **min==max OK** lock guard `>` vs `>=` (revert→RED) · (b) thiếu Max→Conflict "*phải có cả giá Min và giá Max*" not-finalized · (c) min>max→Conflict "*không được lớn hơn giá Max*" · (d) nguồn ĐƠN+Max→Conflict "*kèm giá Max*" wire-bug-guard. +regression assert `Max==null` vào Theory 3b (4 nguồn đơn). **⚠️ Gotcha (self-inflicted-avoided):** prod method 5-param nay → `InvokeApply` reflection helper phải pass 5 args (`{...,maxAmount}`); optional param KHÔNG auto-bind qua `MethodInfo.Invoke` → nếu giữ 4 args = `TargetParameterCountException` phá unit-test 4/4b/4c. Đã fix helper. KHÔNG touch prod.
|
||||
|
||||
## S116 — PE bao gia SO AM regression-lock (test-before guard R2-revised), +9 -> 495
|
||||
**S116 (2026-07-13) PE báo giá SỐ ÂM regression-lock (test-before cho guard R2-revised — critical-algo/financial) — 486→495 PASS (+9 Infra), no-red, NO prod bug:** feature anh Kiệt cho ThanhTien ÂM (phát-sinh-giảm/hoàn tiền NCC = giá THẬT). BE ĐÃ đổi submit-guard `:202-208` `Sum()<=0`→`Count==0`(chưa chọn)/`else All(x==0)`(chưa có giá). 4 nhóm test khớp hành-vi MỚI: **T1** `PeWorkItemBudgetTests` (+1) quote ÂM −20tr KHÔNG chạm PeWorkItemBudget record (FullAmount ngân sách bất biến) NHƯNG CHẢY vào CurrentProposalTotal=−20tr (chứng tách-biệt cột đề-xuất vs ngân-sách, "0 code" kiến-trúc). **T2** `PeMultiWinnerTests` (+2) winnerQuoteTotal=SUM CÓ DẤU khác-winner(+50,−20=30) + cùng-winner-2-dòng(80,−30=50). **T3** `PeSubmitGuardAndBypassTests` (+4, +2 helper `SeedWinnerWithQuotesAsync` params + `BuildV2PeReadyToSubmitWithQuotesAsync`): all-zero[0,0]→BLOCKED "chưa có giá"; pure-neg[−500k]→ChoDuyet; mixed net>0→ChoDuyet; 🔒 **mixed net==0 từng-dòng≠0 [+500k,−500k]→ChoDuyet** = ranh giới phân-biệt All(==0) vs Sum()<=0 (revert→RED). **T4** `PeCcmThresholdFinalizeTests` (+2, +helper 2-signed-quote): NET threshold — [+1.2tỷ,−0.3tỷ]=0.9tỷ<ngưỡng→CCM finalize no-throw + CONTRAST [+1.2tỷ] alone=1.2tỷ≥ngưỡng→Conflict (dòng âm LOAD-BEARING, R-CEO giữ NET). KHÔNG touch prod.
|
||||
|
||||
## S113 — Supplier import v2 dedup + publish-guard (test-after critical-algo + security), +19 -> 477
|
||||
**S113 (2026-07-12) Supplier import v2 dedup + publish-guard TEST-AFTER (critical-algo + security) — 458→477 PASS (+19 Infra), no-red, 🔴 1 BUG-FOUND (REPORTED em-main, NOT fixed):** 2 new files `Services/SupplierImportV2DedupTests.cs` (13) + `Application/SupplierPublishAndListTests.cs` (6). Existing S112 file UNTOUCHED (re-baked ExpectedHeaderTokens=30 \n-token → real tokens khớp → Case9 tự flip LayoutValid=true). **Dedup precedence** existing-MST→existing-Code→batch-MST→batch-Code→New: strip-ws-normalize MST-match · 2-blank-MST=2-insert (blank không index) · same-MST-batch=1-insert+fill-null-skip · **Code-backstop CI** (S112: dedup ở SERVICE OrdinalIgnoreCase, SQLite BINARY KHÔNG bắt "backstop"≈"BACKSTOP" → xanh=chứng không dựa DB) · **MST→A/Code→B = MST-precedence WINS, no silent-clobber** (FillNulls skip Code → A.Code giữ, B untouched). **Publish** `PublishSupplierCommand` (KHÔNG UpdateSupplier #73): gate D2 Publish+blank-Code→Conflict "Cần Mã NCC" · unique-exact→Conflict "đã tồn tại" (⚠️ `x.Code==newCode` DB-collation, SQLite bắt exact-case only — prod SQL CI bắt CI-dup; asymmetry vs import, observation không bug) · unpublish always. ListSuppliers Published t/f/null · GetSupplier DTO.IsPublic. **🔴 BUG:** `NewSupplier` `Code=r.Code!.Trim()` → NRE khi row.Code==NULL (path R4 nháp: parser sinh null ô rỗng + preview classify New no-error → confirm NRE → 500 CẢ batch dbCount=0). Empty ""=OK (T8/T14). Characterization test CHỐT NRE → fix null-safe thì flip NotThrow+draft.
|
||||
|
||||
## D4 — PE sign-off A1 + EDGE-5 + opinion-history (test-before-merge critical-algo), +8 -> 458
|
||||
**D4 (2026-07-12) PE sign-off A1 + EDGE-5 + opinion-history TEST-BEFORE-MERGE (critical-algo bug-fix + security) — 450→458 PASS (+8 Infra, 4 updated in-place), no-red, NO prod bug:** BE đổi `ApplyDrafterBypassOnSubmitAsync` sang **A1** trong `PeSubmitGuardAndBypassTests.cs`. **4 updated + RENAMED** (tên cũ misleading): drafter bypass CHỈ cấp NV dưới THUẦN (Order<minOwn); pointer DỪNG tại minOwn (người soạn ký TAY qua ApproveV2Async); KHÔNG auto-sign opinion chính chủ / KHÔNG auto-terminal-on-submit / KHÔNG auto nhảy Bước. minOwn=1 (drafter Cấp1 hoặc non-contiguous Cấp1+3) → bypass RỖNG (opinion=0, AutoApprove=0). **8 new:** A1 happy-path (drafter ký Cấp2 comment THẬT — canned "duyệt tự động" đã GỠ khỏi prod, grep 0-match) · non-contiguous full-manual-chain đúng thứ tự · EDGE-5 ×4 (non-admin Reject từ DaDuyet/TuChoi → Conflict "trạng thái kết thúc"; **Admin + system[actorUserId=null+AutoApprove] MIỄN** → fall-through "không hỗ trợ" chứng minh qua-guard) · opinion-history ×2 (re-sign đè opinion non-empty → đúng 1 Changelog Workflow/Update EntityId=level.Id ContextNote chứa comment cũ; first-sign / đè-rỗng → 0 row, filter theo EntityId==levelId loại được Trả-lại-changelog EntityId=null). Helpers: `ApproveAsync` (approvedPrice khi ký cấp CUỐI terminal — ApplyApprovedPriceOnFinalize Conflict nếu thiếu, isSystem miễn) + `ReturnToDrafterAsync` (AllowReturnToDrafter default TRUE trên Level). Empty-opinion chỉ reachable qua seed-trực-tiếp (normalizedComment placeholder-hoá whitespace).
|
||||
|
||||
## D3 — Supplier Excel-import BE Phase B (test-before-merge case-collation bug-class), +10 -> 450
|
||||
**D3 (2026-07-12) Supplier Excel-import BE (Phase B) TEST-BEFORE-MERGE (CRITICAL-ALGO + case-collation bug-class) — 440→450 PASS (+10 Infra), no-red, NO prod bug:** new `Services/SupplierExcelImportServiceTests.cs` (10 [Fact]). **Case-collation (THE bug):** ConfirmAsync lowercase `truonggiang` vs DB `TRUONGGIANG` → Inserted=0/Updated=1/count=1 (dedup ở SERVICE `OrdinalIgnoreCase`, KHÔNG dựa DB — SQLite fixture BINARY collation KHÔNG bắt CI-dup, prod SQL Server CI thì có → nếu Ordinal = 500 batch); Preview classify Update. **Fill-nulls SAFE** (non-null giữ / null điền). **All-or-nothing** (1 hard-error→Committed=false + DB unchanged). MapType unknown→NhaCungCap+warning · emoji-strip status → DangHoatDong · valid-layout absolute-index parse (LinkGuq RAW backslash) · no-column-drift (col9 empty→col12 vẫn TaxCode) · #REF! literal→null. **Pattern (reuse):** header xlsx dựng từ `ExpectedHeaderTokens` qua REFLECTION (`GetField(NonPublic|Static)`) → valid-layout test tự đồng bộ khi tokens sửa; ClosedXML in-mem `XLWorkbook.AddWorksheet`+`ws.Cell(r,c).Value=string` GIỮ TEXT (0.105 no numeric-coercion → leading-zero safe). **Spec-drift FLAGGED (không phải bug):** `ExpectedHeaderTokens` = BEST-GUESS ≠ 30 real row-4 token → Case 9 dynamic `LayoutValid==(NormalizeJoin(real)==NormalizeJoin(reflected))` robust 2-chiều, hiện LayoutValid=false; close-review sẽ sửa tokens → test tự flip true.
|
||||
|
||||
## S97 — PE EndsBeforeCeo CONFIG->RUNTIME (spec-change test), +0 (extend in-place)
|
||||
**S97 (2026-07-01) PE EndsBeforeCeo CONFIG→RUNTIME (bug anh Kiệt FDC, spec-change test) — 440 PASS no-red, NET +0 [Fact] (extend in-place):** em-main BE thêm `PurchaseEvaluation.EndedByLevelFinalize` (Mig 60) set true DUY NHẤT nhánh level-finalize `ApproveV2Async`. ListApproved (DaDuyet-only) đọc THẲNG field (`CreateContractFromEvaluationFeatures.cs:196`); List/Inbox ternary `Phase==DaDuyet ? field : subquery`. **Spec-change RED handled:** `PeFinalizeProjectionTests` seed-helper +param `endedByLevelFinalize` → case cũ `peFin` set true; **REPRO case mới `peFinButWentCeo`**: CÙNG wfFin config-có-finalize NHƯNG field=FALSE → EndsBeforeCeo=FALSE (bug: config-true nhưng lên CEO thật). FinalizeStep/LevelName VẪN từ config-subquery (nhãn cấp, không phải cờ). **EF-translate OK** (ListApproved handler no-throw). Service `PeApproverFinalizeTests` +3 assert: #1 finalize→true / #2 advance-CEO→false / #6 opt-out→false (khớp projection repro). No prod bug.
|
||||
|
||||
## S92 — admin-only-modules revoke (test-before-merge SECURITY), +3 -> 434
|
||||
**S92 (2026-06-29) +3 admin-only-modules revoke (test-before-merge SECURITY) — 431→434 PASS, no red:** anh chốt 5 nhóm menu (NHÂN SỰ/VĂN PHÒNG SỐ/CÁ NHÂN/HỢP ĐỒNG/DANH MỤC) CHỈ Admin thấy. Em-main mở rộng `RevokeTemporarilyHiddenModulesAsync` predicate +Contracts/Ct_*/Master/Suppliers/Projects/Departments/Catalog* (cộng dồn S58 Hrm*/Off*/Personal) + TẮT 2 re-grant S65/S69 + narrow `InReviewScope→Pe_*`. `AdminOnlyModulesRevokeTests.cs` (3): NonAdmin-S92Modules-4cờ-false LOAD-BEARING + Admin-untouched + Pe-module-NOT-revoked invariant (root `PurchaseEvaluations` + `Pe_DuyetNcc` không match predicate → giữ user). Reflection harness mirror Office/Hrm seed test. **Gotcha:** OfficeModulePermissionSeedTests + HrmProfilePermissionSeedTests VẪN PASS dù prod đã TẮT 2 call grant — vì test invoke method-CÔ-LẬP qua reflection (private static giữ cho reversibility), KHÔNG chạy SeedAsync chain; thêm 1 dòng header note mỗi file. (ChangePassword S91 10-test ĐÃ merge → trong baseline 431.)
|
||||
|
||||
## D2 — PE Mig 58 multi-winner (test-after + EF translation-smoke), +6 → 419
|
||||
`CreateContractFromEvaluationMultiWinnerTests.cs` (Application ns, 5) cho `CreateContractFromEvaluationCommand` single→multi-winner trả `List<Guid>` (1 HĐ per đơn vị IsWinner). Handler 4-dep `(db, ICurrentUser, IContractWorkflowService, IContractCodeGenerator)` wire THẬT (mirror CreateContractCommandApplicableTypeTests S33): ContractCodeGenerator(db,clock)+ContractWorkflowService — BeginTransactionAsync SERIALIZABLE chạy SẠCH SQLite, KHÔNG try/skip. IdentityFixture. 5 case: (a)≥2 winner→2 ids·2 Contract·Phase=DangSoanThao·SupplierId khớp winner·**GiaTri per-winner = SUM ThanhTien báo giá của ĐÚNG winner (q.PESupplierId==winnerRow.Id)** 140/260·2 mã DISTINCT·pe.ContractId==ids[0] / (b)single→**GiaTri = SUM details.ThanhTienNganSach (LEGACY 800, NOT quote-total 140)**·1 HĐ·TenHopDong null→fallback TenGoiThau / (c)idempotency→ConflictException`*đã tạo HĐ rồi*`+count 2 / (d)0 winner→Conflict`*chưa chọn NCC/TP trúng thầu*`+0 HĐ / (e)not-DaDuyet→Conflict`*DaDuyet*`+0 HĐ. ⚠️**SEED-FK: PurchaseEvaluationQuote HARD FK PESupplierId→Supplier Restrict (cfg:135)** → mỗi Quote ref 1 PESupplier-row thật (random Guid→SQLite 19); Contract.SupplierId/ProjectId no FK vật lý nhưng handler load Project(NotFound)+supplierMap→seed real. `PeListWinnerNamesProjectionTests.cs` (1) TRANSLATION-SMOKE cho EF subquery `WinnerSupplierNames` collection-projection → **EF TRANSLATE OK no InvalidOperationException trên SQLite**: 2/1/0-winner. SqliteDbFixture read-only. No prod bug.
|
||||
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
# Tooling-Auditor Agent — Persistent Memory
|
||||
|
||||
- **S153 (07-26) 2 LƯỢT bookend (open + close) — vòng V1 tooling `[lead seed on-behalf @closeout M9; nguồn = 2 sub-file đĩa]`:** @open **PASS_WITH_FLAGS 7f** (F-1..F-4 CLOSED-verified nợ cũ: Mig-67-row · Budget-bia-mộ · ghost-enum · flip-chain; F-5 LOW ASCII-diagram · **F-6 MED** plugin-assigned `agents/README:222` khai 3 "KHÔNG enable" mà đĩa `true` · F-7 LOW-MED governance/README stale) + MODEL-SELF-REPORT `claude-opus-5[1m]`. @close **PASS_WITH_FLAGS 6f**: ①②③ số PASS — roster **23 khớp 5 bề mặt** (đĩa · VALID_ROLES strip-comment · STATUS:454 · README B1-pointer · agent-memory 23 dir) · 3 persona ctx frontmatter chuẩn (opus+max+8-tool read-only + block Anti-patterns 7/6/6) · rename T11 SẠCH (7 hit tên cũ đều lineage/record, sửa = giả-mạo theo luật S143) · plugin 0-delta (18/15/3 + marketplace 37) · **ghost-wire `session_ctx_kb` ĐÓNG 2-CHIỀU** (caveat ABSENT + `_reader` PRESENT + reader thật `session_ctx.py:528/:537`) · NEW-ALLOC 0-action (skill-matrix phủ 23/23). Mở: F-1 (2 hard-site `:229/:230` — chỉnh ring1 "4": 2 site kia là nấc *used* KHÁC nấc *enabled*) · F-2 governance/README chưa vá · F-3/F-5/F-6 lead vá trong closeout.
|
||||
**Bài mới:** ① **bẫy parse `]`** — regex naive lấy `]` đầu tiên bị dấu `]` trong COMMENT `hmw.js:39` cắt ⇒ VALID_ROLES đếm 18 thay 23; anchor `^\]` mới đúng. ② hub-form verify = **KHÔNG ĐO ĐƯỢC** từ cwd (repo hub ngoài phạm vi) ⇒ khai thẳng thay vì suy. ③ nấc `enabled` ⟂ `used` là **2 TẬP ĐO RIÊNG** — ring1 gộp thành "4" là quá; số đúng = 2 hard + 2 nấc-khác.
|
||||
Tag `[s153, 2-luot-bookend, roster-23-5-bemat, ghost-wire-dong-2-chieu, bay-parse-dau-ngoac, enabled-vs-used]`
|
||||
|
||||
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
|
||||
> Update BEFORE every stop. Tiered Memory v1: L1 HOT (hook hard-limit <17KB) · L2 `archive/2026-06.md` verbatim on-demand · L3 RAG `search_memory`. Keep entry ≤ 1.5K chars.
|
||||
> **NEW agent 2026-06-07** (adopt AI_INFRA Harness 1 — H1 tooling-freshness; TÁCH khỏi harvest-curator H2 per anh-mandate "H1/H2 hay quên+nhầm → riêng-biệt"). Compacted S99 2026-07-02 (19.6KB→~9KB, 12 entry 06-xx → archive NGUYÊN VĂN) · S105 2026-07-07 (19.4→~16KB, S98-S100 → `archive/2026-07.md`) · S106 2026-07-07 (19.7→14.9KB, S102-S104 @start → `archive/2026-07.md`; byte-verified md5×3 @S107) · S107 2026-07-10 @end (17.8→**16.2KB**, S101+S105 @start → archive md5×2) · S109 2026-07-10 @start (17.2→~13KB, S105-end+S106-start → archive md5×2) · S111 2026-07-12 @start+@end (18.35→16.9→~16.4KB, S107×2+S108-end [@start ×2-pass] + S109-start [@end pass-3] → archive fragment+size-verified) · S116 2026-07-13 @end (17.06→13.5→~15.4KB, S110 @start+@end → `archive/2026-07.md` verbatim sed-append +3643B-verified) · S118 2026-07-14 @start (15.7→~15.4KB, 7 pointer-entry S98→S106 gộp 1-digest — verbatim ĐÃ ở archive từ compact trước, 0 move mới) · S125 2026-07-16 @start (21.6→15.8KB, S118-end + S119 @start+META → `archive/2026-07.md` verbatim sed-move +6212B-verified).
|
||||
|
||||
Reference in New Issue
Block a user