Files
solution-erp/.claude/agent-memory/reviewer/archive/2026-06.gist.md
pqhuy1987 c2d01f0dce
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m30s
[CLAUDE] Docs: S152 closeout — bookend hình B trọn 2 đầu + owner (30)(31)(32) + queue memory-ops TRỌN (squash 20 wal:)
- Owner 3-quyết: (30) JUMP để-nguyên-theo-nhịp · (31) 4 persona +NEVER-block (restart ĐÃ THOẢ) · (32) vòng 1→5 AUTO — lô consent gỡ 9 site (5 H1 + ring1-tự-bắt + 3 trio; E-013 EXT)
- Memory-ops TRỌN: A1-A4/D1/D2/R1/B-series — A7 392/392 · mfe 20/20-100% lần đầu · lead-gap drain 24.728→16.485B · strike-ledger + WARN-latch (-Ack = owner-action)
- V4 sleep AUTO đầu: 1 shard thật/16 KÊU · ring4 đầu-đời TRƯỢT-4/5 → 4 fix gist (scribe sub-ring4-close vì return-only)
- Thư model re-stamp: 59ce1d0f → 9c909007 published (G-024a) — adap-report Đính-chính @S152 + sweep 13 bề-mặt LIVE
- Bookend @close: stale 6 FLAG + gap 2 FLAG → vá 8/8; ring2 8/8 ĐẠT (4-A pin-bản-cắt → slot 33) · ring1 48Đ/5T/59-claim
- M9 13 đơn-vị diary (3 S151-deep hồi-tố) · #53 ×10-chắc → tally 60-cận-dưới + errata subject-1b85713
- Session-log 2 run= + completeness-gate 5-vòng ĐẠT · HANDOFF segment S152 (carry 3-đóng/3-mới/23-giữ; slot 33/34)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:58:30 +07:00

90 lines
20 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 — Gist 2026-06 (S51→S57, moved from L1 @S69 curate)
> **distill-gen: 1** (đã nén — KHÔNG nén lại bản này).
> 4-field/record: **VIỆC · KẾT-LUẬN(+file:line/commit) · BÀI-HỌC · BẤT-NGỜ**. Mỗi dòng kết bằng back-resolve `substring:"..."` về verbatim. Nhãn cao/vừa/thấp.
> Verbatim: `2026-06.md` (entry-bullets, chronological earliest-first). Mục lục: `_INDEX.md`. **Archive FROZEN.**
> 9 record = các entry vừa dời từ MEMORY.md L1 lúc S69 curate (giữ verdict + file:line + bài-học).
---
- [cao] VIỆC: S51 P11-C Vehicle+Driver catalog (Mig 44/45 + FE KIND_CONFIG +2 + 5 test) — **spawn, em-main proxy (reviewer return truncated gotcha #53)**. KẾT-LUẬN: **PASS post-fix, 1 MAJOR caught** = Driver FE↔BE required-field mismatch (FE render phoneNumber/licenseNumber/licenseClass OPTIONAL nhưng BE validator `NotEmpty()`+EF `.IsRequired()` → empty submit 400/500); fix FE +`required:true` align Vehicle. Mig 45 = filter 3 HRM unique (gotcha #57). BÀI-HỌC: **parallel fan-out BE∥FE file-disjoint → inconsistency trong SHARED em-main contract chỉ lộ lúc integration; green tests ≠ correct contract (no test chạm empty-optional path); reviewer = the net**. BẤT-NGỜ: transient mid-deploy bundle hash + reviewer self-truncate trước ghi MEMORY → em-main proxy. substring:"S51 P11-C Vehicle+Driver + gotcha #57" → 2026-06.md
- [cao] VIỆC: S52 P11-E AttendanceReport + P11-F MaTicket codegen pre-commit (migration-free) — spawn. KẾT-LUẬN: PASS 0-blocker, 191 PASS — **gotcha #44 attack DISARMED: `[Authorize(Roles="Admin")]` ×2 report endpoints, verify `AppRoles.Admin="Admin"` LITERAL (AppRoles.cs:5) == attribute == FE includes('Admin'); "QTV" (DbInit:1454) = display-code DECOY**; camelCase contract field-for-field; handler `.Year/.Month` IQueryable-translatable, holiday-check in-memory AFTER ToListAsync. MaTicket codegen-on-Create (kanban no-workflow). BÀI-HỌC: **khi spec NAMES attack vector (gotcha #44 role-string), verify LITERAL const value không chỉ attribute-presence**. BẤT-NGỜ: Bash tool = bash không phải PowerShell (Select-String exit 127 → dùng grep). substring:"S52 P11-E AttendanceReport + P11-F MaTicket" → 2026-06.md
- [cao] VIỆC: S52-late Task C ItTicket admin-reassign + Task D AttendanceReport menu-key pre-commit (migration-free, 5 prod file) — spawn. KẾT-LUẬN: PASS 0-blocker — **menu-key `"Off_AttendanceReport"` byte-identical 4 chỗ (MenuKeys.cs:125 == menuKeys.ts:68 == seed parent == Layout staticMap:87)**; FE PUT `/it-tickets/{id}/assign` body MATCH BE record; admin auto-perm via SeedAdminPermissions iterate MenuKeys.All. BÀI-HỌC: **menu-key wiring = verify byte-identity FULL mirror set (BE const + All[] + seed parent + FE menuKeys + staticMap) + confirm target route THỰC SỰ tồn tại (grep App.tsx) — staticMap→non-existent route silently drops leaf (gotcha #50)**. BẤT-NGỜ: lucide `FileBarChart` = deprecated-alias re-export FileChartColumn nhưng vẫn valid (d.ts grep confirm trước flag). substring:"S52-late Task C ItTicket admin reassign" → 2026-06.md
- [cao] VIỆC: S53 Mig 47 Master catalog (Department/Project/Supplier) Code filtered-unique `+.HasFilter("[IsDeleted] = 0")` (4th/5th/6th cumulative gotcha #57 EXT) + 3 test — spawn. KẾT-LUẬN: PASS 0-blocker, **203 PASS****filter string byte-identical HolidayConfiguration:18 (xxd `5b 49 73 ... 30`, spaces quanh `=`); index STAYS unique:true (filter NARROW scope KHÔNG drop uniqueness)**; test seeds IsDeleted=true row → real handler `AnyAsync(Code)` thru HasQueryFilter → NotThrow (RED-before SqliteException confirmed). BÀI-HỌC: **cookie-cutter EXT = byte-compare filter string (xxd) vs canonical sibling + verify index still unique; app-level dup-check = test premise, verify handler có `AnyAsync(Code)` else premise false**. BẤT-NGỜ: implementer claim "2 pre-existing DocxRenderer warn" nhưng clean incremental rebuild = 0 warn. substring:"S53 gotcha #57 EXT Mig 47" → 2026-06.md
- [cao] VIỆC: S54 ItTicket reassign authz Admin-OR-dept-IT cross-stack — controller `[Authorize(Roles="Admin")]``[Authorize]` any-auth, authz moved INTO `AssignItTicketHandler` + new capability query — spawn. KẾT-LUẬN: PASS 0-blocker, 216 PASS — **role-string "Admin" chain traced FULL: `AppRoles.Admin="Admin"`(AppRoles.cs:5)→SeedRoles `Name=roleName`(DbInit:1485)→GetRolesAsync returns NAMES→JwtTokenService:32 `Claim(ClaimTypes.Role)`→CurrentUserService:30-31 `Roles.Contains("Admin")`; "QTV"(DbInit:1458 RoleLabels)=ShortName DECOY; Program.cs no RoleClaimType override**; guard fail-CLOSED khi itDeptId null; capability 0-leak `{canReassign:false,staff:[]}`. BÀI-HỌC: **authz role-string review = trace const→seed Name→GetRolesAsync(names not codes)→Claim→reader AND grep JWT cfg `RoleClaimType` override (none=symmetric); display-code (QTV) = classic decoy**. BẤT-NGỜ: moving authz controller→handler = CORRECT gotcha #44 fix (không phải smell) khi paired BE-computed capability flag. substring:"S54 ItTicket reassign authz Admin-OR-dept-IT" → 2026-06.md
- [vừa] VIỆC: S55 master-data import — Mig 48 `AddProjectMasterFields` (Project +4 nullable Year/Investor/Location/Package) + `SeedRealMasterDataAsync` (62 Project+71 WorkItem+3 Supplier per-code idempotent ungated) + FE ×2 — **spawn, em-main proxy (reviewer truncated gotcha #53 trước verdict)**. KẾT-LUẬN: PASS — em-main completed pending-check `dotnet test` = clean rebuild **216 PASS** (giải tỏa cached-binary 2.76s concern); Mig Up=4 AddColumn/Down=4 DropColumn reversible; per-code idempotent ungated line 118 (reaches prod); FLOCK01 collision skip-demo-wins; runtime Dev proof Investor populates. BÀI-HỌC: **long adversarial review return truncates (gotcha #53) → reviewer emit PASS/FAIL verdict SỚM trước deep re-verify để sống sót; em-main complete được pending-check deterministic (clean dotnet test = fresh build)**. BẤT-NGỜ: cached-binary fast-build nghi → clean test = fresh build giải tỏa. substring:"S55 master-data import pre-commit" → 2026-06.md
- [cao] VIỆC: S55 Phase-1 FE visual redesign pre-commit — 14 fe-admin file VISUAL/CSS-only (NAMGROUP density + SOLUTION brand) — spawn. KẾT-LUẬN: PASS 0-blocker, **verdict-first survived** — npm build fe-admin ✓ 0 TS err; **Button cva variant keys + size STABLE chỉ class VALUES swap (51 call-site safe); Input/Select/Dialog forwardRef+passthrough unchanged; DataTable `Column<T>` type UNCHANGED**; **Be-Vietnam-Pro KEPT (grep @import:3 + --font-sans:22 + font-family:34 unchanged — initial font-drop blocker RETRACTED sau grep)**; Tailwind v4 `shadow-xs`/slash-opacity valid. 2 MINOR: text-slate-400 hint ≈3.5-4:1 borderline-AA (defer). BÀI-HỌC: **font-drop scare = grep 3 load-bearing lines (@import/--font-sans token/font-family) TRƯỚC khi flag — diff hunk lower in file ≠ font removed; emit PASS/FAIL line-1 FIRST (gotcha #53 survival)**. BẤT-NGỜ: Tailwind v4 `shadow-xs` real (v3 shadow-sm renamed) — đừng flag typo. substring:"S55 Phase-1 FE visual redesign pre-commit" → 2026-06.md
- [cao] VIỆC: S56 pre-golive authz **live prod curl** 8 new endpoints — spawn. KẾT-LUẬN: PASS 0-blocker — **8/8 return 401 unauth; admin-authed hrm-configs/vehicles/drivers/leave-balances/attendances all 200 (xlsx 6797B); non-admin Drafter correctly 403 on 2 Admin-only**; **gotcha #44 silent-403 sweep CLEAN: GET /it-tickets/assignable-staff returns HTTP 200 `{canReassign:false,staff:[]}` for non-IT (NOT swallowed 403), handler returns flag không throw (`WorkflowAppsFeatures.cs:466`)**. 1 MINOR: PUT /it-tickets/{id}/assign checks NotFound BEFORE Forbidden (`:496-508`) = existence-oracle leak (mutation fail-closed, post-golive hardening). BÀI-HỌC: capability endpoint = flag-return không throw = đúng gotcha #44 fix. BẤT-NGỜ: NotFound-before-Forbidden ordering = minor info-leak defense-in-depth defer. substring:"S56 pre-golive authz live-curl" → 2026-06.md
- [cao] VIỆC: S57-resume Harness-4 two-tier adopt gate (governance pre-send + pre-commit, no product code) — spawn (self-report `claude-fable-5[1m]` = promote-list direct evidence). KẾT-LUẬN: **PASS-with-fixes 0-blocker** — re-verify ALL GREEN: frontmatter **7 pin `claude-opus-4-8` + 4 `inherit` + 0 `[1m]`-in-frontmatter** + 0 project-pin settings; **evidence track-record 8/8 REAL** vs HANDOFF/STATUS; **nấc G-011 đúng mọi chỗ load-bearing (demote=executed-file·pending-restart, 0 overclaim runtime)**. Fixes: hash PLACEHOLDER trước send + "SENT ✓" premature status-verb + count "(13)"vs"11" + invalid-role typo→rơi 'opus'. BÀI-HỌC: **gate adopt-governance = re-run MỌI grep claim + cross-check evidence vs HANDOFF nguyên văn; n=2 demoted spawn-test double-duty làm inherit-chain proof HỢP LỆ (registry cached=chạy config cũ) nhưng cần phrase rõ**. BẤT-NGỜ: CCD harness cache agent frontmatter → đổi agent .md phải restart CLI mới ăn. substring:"S57-resume Harness-4 two-tier adopt gate" → 2026-06.md
---
> **distill-gen: 2** (S71 curate — KHÔNG nén lại bản này). 10 record dời từ L1 @S71 (over-cap do same-role race). Phần lớn routine pre-commit gate (low-unique-marker) → nén gộp; deep-detail đọc verbatim `2026-06.md` qua `_INDEX.md`.
- [thấp] VIỆC: 6 routine pre-commit gate cũ S33-S49 (S33 Plan B G-H1 Mig 34 SF-6× · S35 G-H2 BE CRUD 16-endpoint SF-8× · Smart-Friend-cumulative-8×-CLEAN · S40 archive-pointer S29-S33 · S43 P11-B LeaveBalance Max-no-truncate · S49 Harness-1/2/3 governance Max-clean). KẾT-LUẬN: tất cả PASS/CLEAN, 0 unique gotcha#/root-cause mới (gate áp-dụng-lặp). BÀI-HỌC: foundation 5-category + Smart-Friend đã ở L1 — các gate này không sinh marker mới. BẤT-NGỜ: N/A (routine). substring:"S33 Plan B G-H1" / "S35 G-H2 BE CRUD" / "S43 P11-B LeaveBalance" / "S49 Harness 1/2/3" → 2026-06.md
- [vừa] VIỆC: 2 die-meta non-deliver (S57bis product-gate die-0-byte ×2 · S60 đợt1 PE submit-guard die mid-run 3rd). KẾT-LUẬN: reviewer chết giữa task → em-main on-behalf gate. BÀI-HỌC: recovery-path = [[feedback_agent_kill_recovery]] (canonical user-memory — marker survive ở đó). BẤT-NGỜ: die-0-byte ×2 cùng điểm. substring:"S57bis product gate" / "S60 đợt1 PE submit-guard" → 2026-06.md
- [vừa] VIỆC: 2 Harness-10 adap-review R2(hmw.js engine)/R3(floor C1-C8) — REDUNDANT (dupe S71 entry giữ L1-top). KẾT-LUẬN: cùng catch C5 L1 over-claim (doc nói hmw.js prompt-builder emit L1, engine no-fs → grep=0 → fixed em-main convention). BÀI-HỌC: marker survive ở L1 S71 + [[feedback_harness10_run_trace]]. BẤT-NGỜ: R2+R3 độc-lập cùng kết luận = high-conf. substring:"Harness-10 adap R2-lens hmw.js" / "Harness-10 adap run-trace folder R3-floor" → 2026-06.md
## CỤM BỔ SUNG [coverage-diff @S152 D2 — máy-trích nguyên-văn + lead-review; KHÔNG phải re-distill, distill-gen giữ]
> Token load-bearing có trong verbatim `2026-06.md` mà gist thiếu — mỗi dòng = token + TRÍCH NGUYÊN-VĂN dòng chứa nó (Ctrl-F token trong verbatim để đọc trọn). Chuẩn gate: gotcha#/Mig/file-ref/guard phải sống trong gist. *(Đính-chính nhãn @lead-review: `#N > 83` = Run/PR-ref CI, KHÔNG phải gotcha — repo max #83; đổi nhãn `ref`.)*
- ref **#283** · trích: "e-checklist PASS 0 blocker') → ship Run #283 PASS prod-verified, bundle rotate both. LEARNED: self-gate em main đứng vững lần 2 (sau S57bis) — checkli"
- ref **#291** · trích: "ual ctor — KHÁC CreateDepartmentCommand #291 CS7036 vì positional-required vs trailing-optional); mirror fe-user==fe-admin SHA256 IDENTICAL (PeDetailT"
- ref **#293** · trích: "`null` backward-compat phiếu thật (Run #293 GET 200); Create/Update +trailing-optional `HoSoLink=null` KHÔNG vỡ call-site (grep 0 manual ctor — KHÁC"
- gotcha **#30** · trích: "k sound (mig 3-file OK pure-ASCII gotcha#30-respect, PUT wired real not-mock). **🟡 MAJOR race STILL PRESENT (carry-over Part1, line 64 entry):** PeDet"
- ref **#313** · trích: "authz) on commit 1d86abc (deployed Run #313) + 1 uncommitted FE-fix. **Uncommitted diff = 2 LOC product only** (`priceMissing` both apps, SHA-identic"
- ref **#381** · trích: "49 Up/Down reversible + 240 test + Run #381 + prod smoke 401/404-control. LEARNED: output-file size=0 + im >5 phút = chết, KHÔNG đợi thêm; KHÔNG re-s"
- gotcha **#42** · trích: "> Foundation (role + bug patterns #42/#43/#44/#47 + 6-category checklist + Smart Friend guard + review essentials) + 6 newest activity entries + S49/S"
- gotcha **#43** · trích: "> Foundation (role + bug patterns #42/#43/#44/#47 + 6-category checklist + Smart Friend guard + review essentials) + 6 newest activity entries + S49/S"
- gotcha **#47** · trích: "dation (role + bug patterns #42/#43/#44/#47 + 6-category checklist + Smart Friend guard + review essentials) + 6 newest activity entries + S49/S43/S35"
- gotcha **#48** · trích: "EAN:** (1) S22 #44 silent-403 · (2) S25 #48 SQLite tie-break · (3) S29 password ≥12 · (4) S29 ApplicableType cross-module · (5) S33 BW test · (6) S33"
- gotcha **#51** · trích: "plete 3 HRM, DbInitializer idempotent + #51 infra-gated, SHA256 mirror, no copy-paste Driver↔Vehicle). **Learned:** parallel fan-out (BE∥FE file-disjo"
- gotcha **#66** · trích: "full 50-900 so brand-800 valid); gotcha #66 — 0 gradient/dark-bg headings added (all headers on light surface use accent-ink text-brand-800/{accent}-7"
- Mig **Mig 43** · trích: "th cumulative gotcha #57 (after Holiday Mig 43 S45 + HRM ×3 Mig 45 S51). 3 Master configs (Department:18/Project:19/Supplier:24) Code unique index `.I"
- Mig **Mig 49** · trích: "thz key-set + role-string vs AppRoles + Mig 49 Up/Down reversible + 240 test + Run #381 + prod smoke 401/404-control. LEARNED: output-file size=0 + im"
- Mig **Mig 54** · trích: "- **2026-06-18 (S72ter-WIRE Mig 54 cross-stack-wire + verify-fix lane — uncommitted priceMissing, PASS no-new-deadlock):** Complement to S72ter-AUTHZ"
- Mig **Mig 56** · trích: "6-19 (S76 Part1 PE budget MA-TRẬN 3 cột Mig 56 — uncommitted, PASS w/ 1 MAJOR race + 2 MINOR):** Form ngân sách 1-cột→ma-trận [Dự án|PRO|CCM]. Entity"
- Mig **Mig42** · trích: ":** 14 file (LeaveBalance entity+config+Mig42 + Features + Controller + deduction hook + Create/Update LeaveType guard + embed balance + FE×4 + tests)"
- Mig **Mig46** · trích: ", no stray. Mig 47 latest in seq (after Mig46 ItTicket SLA). **Learned:** cookie-cutter EXT of proven pattern → discriminator = byte-compare filter st"
- Mig **Mig47** · trích: "status = exactly 3 configs + snapshot + Mig47 (2 untracked) + 1 test + 2 MEMORY; no FE, no extra mig, no stray. Mig 47 latest in seq (after Mig46 ItTi"
- Mig **Mig54** · trích: "ad); type files differ pre-existing BUT Mig54 fields diff-identical. Setter handlers fail-closed Forbidden-before-side-effect, PRO Min<=Max validator,"
- Mig **Migration 3** · trích: ". priceMissing disable Xác nhận đúng. **Migration 3-file OK** (Mig 54 additive-nullable, Designer 5 col, snapshot). **Tests 334 PASS** (45 Dom+289 Inf"
- guard-kw **cascade** · trích: "*3 excluded keys STAY HIDDEN — decisive cascade check:** `Off` is NOT one of the 4 inherit-roots in GetMyMenuTreeQuery (:56-59,:70-73,:80-83 = Contrac"
- guard-kw **Cascade** · trích: "eeProfiles` 7 table UNIQUE indexes + FK Cascade. SeedDemoEmployeeProfiles NOT gated DemoSeed (gotcha #51 ✓). gotcha #50 Layout staticMap mirror ✓. **3"
- guard-kw **lost-update** · trích: "dmin)]`. **2 MINOR defer:** concurrency lost-update UsedDays (no RowVersion — human-sequential accept) · stale line-num comment. Verdict PASS. Tag `[s"
- guard-kw **RowVersion** · trích: "** concurrency lost-update UsedDays (no RowVersion — human-sequential accept) · stale line-num comment. Verdict PASS. Tag `[s43, p11b-leavebalance, ma"
- guard-kw **Serializable** · trích: "on-failure — codegen commits seq in own Serializable tx BEFORE `Add(e)+SaveChanges`; ticket-insert fail → burned IT/2026/NNN gap. NOT new defect = ide"
- guard-kw **SERIALIZABLE** · trích: "✓. **3 MINOR defer:** EmployeeCode race SERIALIZABLE low-risk · Update 3 bool not nullable (partial reset) · Delete DateTime.UtcNow direct. Verdict PA"
- file-ref **ApprovalWorkflowV2AdminFeatures.cs** · trích: "/ `ccmBudgetEditors=CostControlAdmin` (ApprovalWorkflowV2AdminFeatures.cs:155-157 + PurchaseEvaluationFeatures.cs:976-978) đảo-chiều set-lookup 3-que"
- file-ref **DbInitializer.cs** · trích: "prod files: MenuKeys.cs (const+All[]), DbInitializer.cs (1 seed tuple), fe-admin {menuKeys.ts, Layout.tsx staticMap, ItTicketsPage.tsx}. **Independen"
- file-ref **HrmConfigFeatures.cs** · trích: ", Smart Friend 8× CLEAN):** 2 NEW file `HrmConfigFeatures.cs` 439 + Controller 137. build clean, 130/130 PASS. Cat1: 0 mock, 8 ConflictException (Holi"
- file-ref **ItTicketsPage.tsx** · trích: "min {menuKeys.ts, Layout.tsx staticMap, ItTicketsPage.tsx}. **Independent re-verify GREEN:** `dotnet build SolutionErp.slnx` 0-warn/0-err · `npm run b"
- file-ref **Layout.tsx** · trích: "(1 seed tuple), fe-admin {menuKeys.ts, Layout.tsx staticMap, ItTicketsPage.tsx}. **Independent re-verify GREEN:** `dotnet build SolutionErp.slnx` 0-w"
- file-ref **PeApprovedPriceFinalizeTests.cs** · trích: "lt-finalize bypass price). Test header `PeApprovedPriceFinalizeTests.cs:27-31` tự-ghi OBSERVATION report-em-main KHÔNG-fix + reflection-invoke isolati"
- file-ref **PeSuggestedPriceFeatures.cs** · trích: "luật chỉ-touch-2-file. **(a) PASS** — `PeSuggestedPriceFeatures.cs` cả 2 setter ForbiddenException TRƯỚC mọi mutate+SaveChanges (load+NotFound→role-g"
- file-ref **Permission.cs** · trích: "→read+create=true, update/delete=false (Permission.cs defaults false anyway). (4) **3 excluded keys STAY HIDDEN — decisive cascade check:** `Off` is N"
- file-ref **PurchaseEvaluationFeatures.cs** · trích: "valWorkflowV2AdminFeatures.cs:155-157 + PurchaseEvaluationFeatures.cs:976-978) đảo-chiều set-lookup 3-query/req no-N+1; khớp 1:1 gate thật canEditPro/"
- file-ref **PurchaseEvaluationWorkflowService.cs** · trích: "NO deadlock — decisive:** submit-guard `PurchaseEvaluationWorkflowService.cs:174-216` enforces (ALL paths incl Admin/system) winnerQuoteTotal>0 (line1"
- file-ref **memory.ps1** · trích: "apshot) → re-run `scripts/measure-agent-memory.ps1` + curate L1→L2 (additive, archive/ + _INDEX exist). (G2 MED) **stale memory claims** — Harness-9 u"
- file-ref **menu.ts** · trích: "ub) — Layout maps to REAL route. `types/menu.ts` correctly NOT mirrored (`key:string` not typed union). admin auto-perm via `SeedAdminPermissionsAsync"
- file-ref **realtime.ts** · trích: "00KB chunk + INEFFECTIVE_DYNAMIC_IMPORT realtime.ts — git-confirmed none introduced, @import lines untouched in diff). **Regression Cat1 ALL preserved"
- file-ref **types.ts** · trích: "256 page 4bcaf2f IDENTICAL both apps** (types.ts correctly NOT identical — admin AttendanceReportDto vs user HrDashboardDto diverge below; added Assig"
### BỔ-SUNG-2 [F1/F2 sau Fidelity-gate @S152 — mở đuôi infra {yml,yaml,json,slnx,csproj,sql,config} + guard IsUnique/optimistic. N/A CỐ-Ý (F5): bundle-hash xoay #69 · tên-giả phép-thử ZZfakehash* · đuôi .md]
- guard-kw **IsUnique** · trích: "ect:19/Supplier:24) Code unique index `.IsUnique()``+.HasFilter('[IsDeleted] = 0')` + Mig 47 (3-file) + 3 new tests. **Independent re-verify ALL GR"
- guard-kw **optimistic** · trích: "ll Save khi mut.isPending HOẶC onMutate optimistic-merge HOẶC await invalidate. **🔵 MINOR:** (a) `parseVnd` strip `.` → '1.5'→15 (input cho `.` nhưng"
- file-ref **budget.json** · trích: "or-codebase **29819B** (>25600). memory-budget.json `measured` STALE (reviewer 24795/inv 24052 = S70 snapshot) → re-run `scripts/measure-agent-memory."
- file-ref **memory-budget.json** · trích: "estigator-codebase **29819B** (>25600). memory-budget.json `measured` STALE (reviewer 24795/inv 24052 = S70 snapshot) → re-run `scripts/measure-agent-"
- file-ref **package.json** · trích: "tracked `runs/`. NO product/test/csproj/package.json/migration → test baseline 306 untouched, deps N/A. **Spec path trap:** spec said `runs/...` but a"
- file-ref **tsconfig.app.json** · trích: "m exactly) · fe-admin + fe-user `tsc -p tsconfig.app.json --noEmit` BOTH exit 0 clean. **#2 CHÍ MẠNG role-string 'Admin' CONFIRMED REAL (full chain tr"