Files
solution-erp/.claude/agent-memory/reviewer/MEMORY.md
pqhuy1987 398d343403
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m48s
[CLAUDE] Docs: S149-S150 closeout — bookend lượt đầu end-to-end (hình B) + 2 arc đóng + tally #53 chốt 45
- Arc-1 hội-tụ-bookend (rename 5 vai + 4 máy PS1 + C9-C12) + arc-2 adap-backlog 23/23 + probe Opus-5 khép (S149)
- Bookend @close S150: wave 6 vai (4 đo + 2 KIỂM) → 20 FLAG disposition từng-dòng; ring1 31/34-ĐẠT, ring2 10/10 + M-1 view-stale-role-desc
- Khoá _frozen_until_owner CẮM trước h24-signal-write (frozen-held in thật); 9 class FIRE; JUMP dải {5,4,4,3}+asym{1,4} chờ anh #21
- STATUS bump CURRENT S149-S150 + 2 khối Recently Done; HANDOFF segment mới + re-stamp đủ-slug + (17)(18)(19) lật + (14) viết lại + 6 slot #21-#26
- K2 posture-A @engine PHẦN K + K5 luật TÁCH vòng-đo-mới @session-end (O-2/O-3 OWNER-DELEGATED execute)
- sleep-doc derive-monitor-set (bỏ hardcode 4-tên); spawn-model-audit desc/comment fix; h24-signal-write param-default fix (first-live bug)
- M9 on-behalf ×3 (tooling + inv-cb F3 + reviewer F4); ring1/ring4 nhà seed; ring2 3 cite-dead vá
- Sổ garble #53 derive-from-body chốt 45 + sub-class ngược-#53/skeleton-ruột-rỗng (ghi-đĩa CẦN-KHÔNG-ĐỦ)
- Session-log S149-S150 (Sàn-5 đăng-ký 6 run=) + closeout-synthesis dạng-1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:17:05 +07:00

104 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Reviewer Agent — Persistent Memory
- **[verbatim → git 8b6df0a closeout] S146 (07-22) PRE-COMMIT spec-v2-applied (governance 20 file) — 2 MAJOR THẬT (cả hai của LEAD); nấc `verified` tự-chạy-lệnh không-tin-lead:** F1 `session-end.md` còn `hook-3-path` GẠCH-NỐI dù worker CE đã chỉ đích-danh (class "residual có người chỉ tận nơi vẫn rớt") + bất-đối-xứng nội-bộ (`pause.md` đã 4-path). F2 phép quét cardinality của lead siết LỆCH-TRỤC (co-occurrence CÙNG-DÒNG + 1 mẫu-chữ) → re-run HEAD tiền-vá lọt 4 ca thật gồm chính F1. F3 HELD (git show da7ee8a: hook 4-path + `-File` re-đọc mỗi Stop). 🔴 Bài rút: lead sửa 1 phép quét 4 lần/phiên vì mã-hoá ý-định NGỮ-NGHĨA vào regex; nấc đúng = lưới-soát-cho-người + allowlist CÓ TÊN + use⟂mention; lần-4 = citation-trap (dò bắt chính nốt-vá vì nó trích giá-trị cũ).
- **[→ archive/2026-07.md @S145-curate] S145 Axis-E lane — FAIL 2C/1M/4m:** cross-cut seam catch (hook 3→4 path sessions/ orphan phá Sàn-3 tiep.md; session_ctx_kb=64 nghịch owner + ghost-wire #H18). LESSON: bất-biến chia-đôi giữa 2 axis nằm ĐÚNG SEAM → chỉ cross-cut sweep bắt.
- **[→ archive/2026-07.md @S145-curate] S145 lane-4 (Axis-D) — PWF 2M/1m:** phép-4 LANDMINE (`agent-memory/ring1-audit/` EMPTY, auto-fires close ⇒ phép-4 FAIL). LESSON: 'vai-có-sổ' acceptance ⇒ MUST `ls agent-memory/<role>/` (folder≠sổ).
- **[→ archive/2026-07.md @S145-curate] S145 C7-lane (Axis A) — PWF 1C:** spec "4 surface→2" stale-fix FALSE (4 caller THẬT); grep-"4 surface"=0-hit = ANTI-TEETH Goodhart. LESSON: stale-fix verify caller-trên-đĩa; 2-script-same-suffix = conflation-vector.
- **[→ archive/2026-07.md @S145-curate] S145b (07-22) GATE roster #2/#3 ring2-audit+ring4-audit (18→20) — PASS 1m:** implementer vá ĐÚNG mọi S145a-finding + tự sweep 2 NUMERIC site ngoài checklist. 1 MINOR measured-label: `README:249` "17 folder" falsified by ls=18 (ring1-audit RỖNG). LESSON: đếm VALID_ROLES = per-file grep bidirectional KHÔNG regex (hmw.js `[2]`/`[S110` comment lừa parser).
- **[→ archive/2026-07.md @S145b-curate] S145a·S143 (digest, archived):** S145a NUMERIC "roster 17" hardcode trốn name-enum sweep ⇒ sweep repo-wide CẢ numeric LẪN name-enum (superseded S145b PASS) · S143 CLASS `bằng-chứng-tự-huỷ-sau-squash` (cite outward = commit SỐNG-sau-squash) + số neo-mốc + errata CẤM sửa file đã-stamp + #53 ghi-đĩa-trong-lúc-làm.
- **[→ archive/2026-07.md @S140/@S134] S139·S134b·S133 (digest, archived):** S139 re-measure MỌI acceptance từ git HEAD + no-self-exempt (chấm cả file CHÍNH VAI MÌNH); "measured" sống CHỈ KHI falsify-path CHẠY ∧ đứng · S134b insertion-only + `grep '^-'`=0 chắc hơn diff-mắt · S133 "mọi nhánh set X" phải grep CẢ assignment-qua-BIẾN (#81).
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
> Update BEFORE every stop. Tiered Memory v1: L1 HOT cap ~17KB (hook 24.4KB read-limit) · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
> Full verbatim history pre-S40 → git `d2f52ba` + `archive/2026-05-q1..q2.md`; S51→S76 detail → `archive/2026-06.md` (S69/S70/S71/**S80** curate). Archive map: `archive/_INDEX.md` + per-period `.gist.md`.
## 📁 Area memory (L2 on-demand — Read khi review vùng tương ứng)
- [S62 PE budget soft-warning](project_s62_pe_budget_soft_warning.md) — PASS: hard-block→soft-warning; submit-guard intact + validator giữ `BudgetPeriodAmount>0`, row8 negative-safe (additive-only). Validator class `PurchaseEvaluationFeatures.cs:317`.
- [Wire/mirror claim verification anchors](feedback_wire_claim_verification_anchors.md) — sha256 twin-file · `git diff -U0` isolate true-adds · `allowNegative` bleed check · guard-still-intact grep.
- **S89 trio** ([sectionB](project_s89_pe_sectionb_review.md) · [endsBeforeCeo](project_s89_pe_endsbeforeceo_plan_review.md) · [finalize-note](project_s89_finalize_note_plan_review.md)) — adjustMut share race + authz-lens ≠ concurrency-lens · FE 4 render-sites plan-missed-2 · ground-truth-accurate-nhưng-gaps.
- **S101 H18/H19 WF2 + LANE-C — PWC/PASS:** content-hash ≠ commit-SHA (hex strip/no-strip) · exact-token sweep misses paraphrase → widen concept-phrase. → `archive/2026-07.md`.
- [S103 H20+crystallized-backfill review](project_s103_h20_crystallized_backfill_review.md) — WF2 PASS; 6/6 hash recompute MATCH + 4 already-met verified. Lesson: multi-axis warning phải nằm trong OUTPUT của script (reader chạy inline), không chỉ doc.
- [S111 PE sign-off 6-decision design review (schema/history lens)](project_pe_signoff_history_schema_review.md) — GO-WITH-ADJ; D5 opinion-history: append-only table, REJECT version-col (drops UNIQUE + breaks UPSERT).
- **PE per-hạng-mục series ×5** ([cardinality#3](project_pe_multiwinner_perhangmuc_review.md) · [BE-financial](project_s114_pe_multi_ncc_perhangmuc_financial_review.md) · [spec-l3](project_pe_multi_ncc_perhangmuc_specreview.md) · [IMPL](project_s114_multi_ncc_perhangmuc_impl_review.md) · [neg-quote](project_pe_negative_quote_correctness_review.md)) — derived src-of-truth: re-derive MỌI write-path KỂ CẢ Delete · grep field-NGUỒN không chỉ field-đọc · sign-loss: defer-parse tới field-chung mọi mutation.
- [S113 Supplier import v2 close-review (owner anh Kiệt)](project_s113_supplier_import_v2_review.md) — GO-WITH-ADJ 2 must-fix (consumers không pass published=true → drafts leak). Lesson: "filter added" ≠ "drafts hidden" — grep-all-consumer + create write-path.
- [S118 Procurement master-access seeder review](project_s118_procurement_master_access_review.md) — PASS(cond); MAJOR Reports.Read leaks financials + Suppliers.Update grant ≠ edit. Lesson: menu-flag grant ≠ API capability; bare `[Authorize]` GET = open-to-all.
- [S123 governance 4-change review (backtick-guard + H24-3 + retire dạng-3 + mark)](project_s123_governance_4change_review.md) — PASS_WITH_FIXES; CAUGHT H24-3 thiếu enclosure-guard mà cùng diff vừa chứng cần (gen-2 citation-trap) + greedy `.*` lấy `(S<N>` CUỐI≠MAX + lý-do-retire áp cho dạng-2 thì giết C8. Q5 "HOÀN-THÀNH mark" = nguỵ-biện. Q8 ENDORSE không-bump.
- [S147 Project whitespace-dupe merge verify](project_project_dupe_merge_verify.md) — 7/7 PASS(2 FK-terminology corrections); "FK Projects" COMMENT ≠ physical FK (sys.foreign_keys=0 to Projects, all loose-Guid); seed-durability FORCES survivor=no-space blanket; INNER-join+filter=silent-vanish→repoint-before-soft-delete; prod ref-dist unverifiable (Server=localhost+secret).
---
## 🎯 Role baseline
Adversarial pre-commit reviewer SOLUTION_ERP. Read-only verify + live curl prod UAT (`*.solutions.com.vn`). Tools: Read, Grep, Glob, Bash (curl + git diff + sqlcmd read) + 5 RAG MCP. Skills: `dependency-audit-erp` + `contract-workflow` + `permission-matrix`. Output: PASS/FAIL + concrete issues file:line. NEVER write code.
---
## 🚨 Recurring bug patterns (catch priority)
- **#44 Silent 403 class-level Authorize quá strict** — Drafter dropdown empty silent (TanStack catch silent → UI empty). Grep `\[Authorize\(Policy=.*\)\]` class-level + curl non-admin expect 200. Fix: class-level `[Authorize]` only (any authenticated); POST/PUT/DELETE giữ `[Authorize(Policy="X.Create")]`.
- **#43 Step.Order ≠ index 0-based** — `Where(s=>s.Order==i)` wrong row. Fix: EF query → in-memory `OrderBy(Order).ToList()` → index.
- **#42 Dual schema V1/V2 — Service phải branch** — `if (entity.ApprovalWorkflowId is Guid awId) ApproveV2Async else V1Legacy`.
- **Wire BE claim** — grep diff `// Mock`/`alert(`/no POST-PUT-DELETE call + live curl expect 2XX. Severity CRITICAL block.
- **#70 FE absolute-set stale-echo race** — N fields cùng-cột share 1 mutation + echo sibling từ server-snapshot (`bs`) + `invalidate()` fire-and-forget (không await) → lưu 2 ô liên-tiếp đè mất. Window mở SAU `isPending=false` (btn re-enable), KHÔNG lúc in-flight. Catch: đếm field-cùng-cột share mutation + check invalidate awaited; fix = `useIsFetching` gate nút Lưu tới khi refetch land.
- **#71 enum proxy-predicate pollution** — thêm enum value vào entity dùng-chung → UI/guard phân-loại theo PROXY-predicate (`supplierId===null`) thay vì enum tường minh → value mới lẫn nhầm phân-loại + false-pass guard. Catch: grep mọi field-proxy predicate, loại value mới tường minh; build-verify TỪNG app.
- **Cross-module security mirror (S29 Smart Friend)** — khi mirror entity/Command cross-module (PE→Contract→Budget V2), focus data-shape MISS security guard. Pattern: `aw.ApplicableType == ExpectedType` validate ON Create BEFORE instantiation (mirror `PurchaseEvaluationFeatures.cs:62-77`). Attack: Drafter forge POST với `approvalWorkflowId` của module khác → FK Restrict chỉ check Id-existence NOT ApplicableType → wrong-scope pin. Re-verify `IsActive`+`IsUserSelectable` server-side. Password ≥12 chars. Severity MAJOR.
- **#17 EF migration 3-file** — `git diff --name-only | grep Migrations/` expect 3 (target + Designer + Snapshot).
---
## 📋 6-category checklist (EVERY review)
- **Cat 1 Wire BE/feature claim:** grep mock markers diff + `await api\.(post|put|delete|patch)\(` + live curl POST/PUT/DELETE if deploy claim + status matrix.
- **Cat 2 Schema integrity:** 3-file rule Mig + column types vs entity def. Reference `docs/gotchas.md` (71 active).
- **Cat 3 Security:** `[Authorize]` class-level ALL new controllers + per-action policy admin-scoped (gotcha #44) + FE PermissionGuard + menuKeys.ts mirror BE MenuKeys.cs + FluentValidation + EF parameterized.
- **Cat 4 Code quality:** `dotnet build SolutionErp.slnx` 0 err + `npm run build` × 2 app (TS6 strict) + tests baseline **354 PASS** (Phase 9 UAT exception OK) + no `--no-verify` + anti-fiddle (scope drift >20% LOC = FAIL) + mirror 2 FE app §3.9.
- **Cat 5 Test coverage:** new helper → xUnit · new endpoint → integration · bug → regression test-before-fix. Phase 9 UAT test-after default OK (`feedback_uat_skip_verify`). Baseline 354.
- **Cat 6 Writing-quality (Harness-7, S64):** outward text (verdict gửi anh / report) = tiếng Việt câu hoàn-chỉnh đủ dấu đúng ngữ-pháp; describe issue + acceptance criteria, NOT code edits. Escalate disagreement explicit.
---
## ⚠️ Anti-patterns + 🛡️ Smart Friend guard
1. ❌ Recommend code edits (only describe issue+criteria) · 2. ❌ Skip live curl if deploy claim · 3. ❌ Accept "wire" without grep proof · 4. ❌ Defer to em main authority (escalate explicit) · 5. ❌ Skip MEMORY · 6. ❌ **Lower bar match em main** (Smart Friend Cognition anti-pattern).
**Smart Friend (Cognition):** NEVER lower bar. Em main code fine → PASS. Em main issues → FAIL with specifics regardless social pressure. "Quality ceiling set by primary, not escalation." Value = raise quality through catch.
---
## 🧠 SOLUTION_ERP review essentials (S80 verified — re-ground từ docs/STATUS.md canonical)
- **Tests baseline:** **354 PASS** (45 Domain + 309 Infra · 0 fail/skip). Must increase khi feature added (§7); Phase 9 UAT exception (`feedback_uat_skip_verify`).
- **Gotchas:** **71 active** (`docs/gotchas.md`, format `### N.`). Latest: #69 bundle-hash non-determ (deploy rebuild-FE-uncond rotate) · #70 FE stale-echo race (useIsFetching gate) · #71 enum proxy-predicate pollution · #66 Tailwind v4 unlayered `h1-h4` color thắng utility · #58 EF read-modify-write lost-update→ExecuteUpdate atomic.
- **Migrations:** **57 latest `AddPeSuggestedPriceNotes`** (path `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/`). PE-budget: Mig 50 `PeWorkItemBudgets` per-gói-thầu (DROP module Budget cũ) · Mig 54 giá-đề-xuất PRO/CCM + giá-chốt · Mig 55 CcmNote · Mig 56 ProInitial/ProAdjust split · Mig 57 ghi-chú-giá PRO/CCM.
- **Endpoints:** ~253 · **88 SQL tables**.
- **Identity password ≥12 chars** (reject 11-char). Test creds: admin `admin@solutions.com.vn/Admin@123456` (full) · UAT `nv.test@solutions.com.vn/TestUser@123456` (Drafter CCM).
- **Prod:** api/admin/eoffice.solutions.com.vn. Bundle live admin `CsJetgZH` / user `BVS0ApIm` (Run #330). **Pin:** MediatR `12.4.1` (flag `Version="14`) · Swashbuckle `6.9.0` · Node CI `20.x`.
- **Conventions:** `docs/rules.md` (§1.1 outward writing, §3.9 mirror 2 FE, §5.2 commit, §6.5 docs narrative, §7 test timing, §2.8 pin).
---
## 📅 Recent activity (compressed — full verbatim → `archive/2026-06.md` + `archive/2026-07.md` via `archive/_INDEX.md`)
- **S147 (07-23) DIAGNOSIS-review PE attach TraLai (no diff — verify root-cause + stress fix) — Diagnosis PASS 5/5, fix CORE-safe/EXT-unsafe:** 5 claims verified from disk; BE-no-guard CONFIRMED **intentional** by S78 changelog L9 ("handler KHÔNG guard drafter-only → approver upload no-403") + sole pipeline behavior=ValidationBehavior. 🔴 **MAJOR blind-spot:** `attachEditable=isDrafter&&isEditablePhase` SAFE for GeneralAttachmentsSection (:2013 readOnly=raw, no carve-out) but UNSAFE for SupplierAttachmentsCell (:2758) whose readOnly=**itemsReadOnly** (`readOnly&&!approverEditMode`, Mig28-F3 ChoDuyet approver-edit) → naive REPLACE breaks approver QuoteDocument edit in ChoDuyet; SAME gap in optional BE guard (carve-out {ChoDuyet+ApprovalAttachment} misses ChoDuyet+QuoteDocument). **Scope trap:** isDrafter@:140 in MAIN scope, OUT-of-scope at :2013/:2758 (child comps take only {ev,readOnly}); changing :421 over-broadly hits HoSoLinkRow:2017. **Completeness:** WORKSPACE (readOnly=false, picker editableOnly∋TraLai) already edits comparison-doc in TraLai → bug is LIST-detail-only (:574/:669 hardcode). LESSON: **decouple a gate → trace if shared prop already carries a carve-out (itemsReadOnly ≠ raw readOnly); "same fix" for sibling surface may hit a DIFFERENT gate source.**
- **[→ archive/2026-07.md @S126/@S134] S123·S124·S125·S129·S131·S131b digest (all archived):** S131b follow-up phải GIỮ con-số source · S131 số-atomic-đúng vẫn fencepost → hero-ratio re-derive từ raw ([topic](project_s131_h24_h22_3gap_outward_gate.md)) · S129 writer-only = NỬA-VÁ + quick-test tự-chạy = chứng rẻ nhất · S124/125 do-token trap → re-Read full + sibling-test 2-CHIỀU (MATCH⇒file-bệnh·FAIL⇒verifier-bệnh) · S123 🔴 #53 ghi diary TRƯỚC return + vá-1-lớp grep MỌI matcher cùng-lớp ([topic](project_s123_governance_4change_review.md)).
- **Digest S93→S117 (verbatim → `archive/2026-07.md`; 1 mệnh-đề/entry):** S93 code-gate re-derived denom · S97 default-flip byte-mirror SHA ×2 · S98 Windows byte-verify = .NET (MSYS strip
báo sai) · S100 HELD stale run-id NOT-stamped · S101 persist-claim cần reader-side · S108 outward-claim "đã sửa X" phải cat X trước gate · S109 gist meta-count ≠ disk · S110 claim-về-code grep lại kể cả reword · S111 nâng-nấc-quên-sync cùng-diff · S115 verify EACH regex-alt by-hand · S116 persist-claim = tracked + 0-drift · S117 2-tier guard compare SUM-EXPRESSION.
- **S92 PROD-security hide 5 menu-groups admin-only — PASS (1 note):** → [project_s92_admin_only_modules_revoke.md](project_s92_admin_only_modules_revoke.md).
- **June-2026 digest — LESSON-ONLY (verbatim → `archive/2026-06.md` + `_INDEX`):** merge-distill fabricates false-specificity ⇒ QUALITY gate AFTER presence · sha = self-declared NOT recompute · fail-closed guard BEFORE terminal-state + server-recompute · TRACKED = check-ignore ≠ ls-files · menu-hide ≠ API-lock · single→multi stops at display-layer.
- **[→ archive/2026-07.md @S128/@S134] S112·S126·S127·S128 digest (all archived):** S112 GO — derive guard từ ENDPOINT authz, self-flip ≠ external-accept ([topic](project_s112_supplier_import_review.md)) · S126 gate — AGGREGATE cumulative KHÔNG vào outward artifact, "ba việc"=2 ASK · S128 — direction-of-error quyết mức lỗi outward + brute-force sha-variant TRƯỚC phán tamper + Get-FileHash ≠ body-sha · S127 — hedge broadcast bằng MỞ config THẬT.
---
## 🔄 Curate trigger
- Hook-cap **>17.1KB** (24.4KB read-limit — đổi từ ~30KB cũ, S109) → archive recent → L2 `archive/<period>.md` (append additive) + `_INDEX.md` substring pointer. Stale >3mo → remove.
- **S145-curate (self lane-4, 2026-07-22, hook 22.6KB→~17.7KB):** concurrent 5-lane /fable-clone session (mỗi lane +~1.6KB fresh entry). Moved 4 fresh verbatim (S145 Axis-D-self·Axis-E·C7-lane·S145b) → `archive/2026-07.md` @S145-curate marker + verify `grep=4` moved-not-cut → collapsed L1 to pointers. S145a/S143 đã digested (linter). Residual ~17.7KB (>17.1 soft) defer — không cut-without-move mid-return (S140 precedent).
- **Prev curates (digest):** S140 (S139·S134b→@S140) · S134 (8 verbatim→@S134, seal 6/6+2) · S128 em-main (md5 e5218d2f) · **S102 recovery: cut-not-moved ×5 @`f229b07` — Lesson: L1-shrink kèm "→archive" = BẮT BUỘC grep moved-not-cut trước khi trust** · S116·S113·S109·S80·S71·S70·S40.
## S149 (2026-07-24) — gate hội-tụ-bookend [LEAD GHI ON-BEHALF @S150 — M9/B3 theo H2-F4 (1 invocation thật → 0 entry); nguồn: `runs/2026-07-24-S149-hoi-tu-bookend/sub-reviewer-hoi-tu.md` 15.733B]
- `/fable-real reviewer` gate spec hội-tụ-bookend: **GO-WITH-FIXES 1C/6M/4m** (CLEAN 218K, 0 garble) — spec v1→v2 trước wave implement 5-lane Opus (5/5 done 946K 0-garble). Lưu ý sổ: lượt gate adap-backlog `wf_f4e4c006` KHÔNG tính invocation vai này (reviewer-lane **skeleton-ruột-rỗng** — khung 274B, 0 append, return+resume đều fail → em-main-solo re-do; xem sổ garble sub-class @S150).