# S134 — PE lũy kế TẠM TÍNH vs CHÍNH XÁC (2026-07-17) **Commit:** `6664a61` (11 file: 4 BE + 6 FE + 1 test) + `e53a693` (docs S133 closeout, cùng push) — **squash §5.0 trước push, 9 `wal:` local tiêu, 0 lọt origin** · **CI:** Run **#399** VERDICT **GO 5/5** (5m27s, return CLEAN) · **Test:** 520→**528** (45D+483I) · **Mig:** 0 (Mig 67 giữ top, 89 bảng) · **Bundle:** admin `BVCukFP5`/`CBzUlgOA` · user `DoxyEOxh`/`BHsBUA8e` · **Lead:** Fable 5 · HMW-ON · run-folder `.claude/workflows/runs/2026-07-17-S134-pe-luyke-tam-tinh/` ## Đề bài (UAT anh Kiệt FDC — chat 15/07, chốt 16:10 "Vậy em xử ký theo hướng này đi") Lũy kế PE chỉ bắt phiếu DaDuyet (Kenny S117) → phiếu chưa duyệt không góp vào phiếu sau. Vì **"cung đặc thù"** (phiếu sau trình khi phiếu trước chưa duyệt), anh Kiệt yêu cầu "vẫn cho bắt lên và tính toán, note nó màu gì đó… để đến bước cuối của CEO hay người duyệt thay cần phải duyệt phiếu trước phiếu này". Hướng chốt (em đề xuất, anh Kiệt duyệt ♥): **lũy kế TẠM TÍNH = tất cả** ⟂ **lũy kế CHÍNH XÁC = chỉ phiếu đã duyệt** (giữ nguyên). ## Ship - **Ground-truth lật khung (fable-real invest):** row 1 ĐÃ gồm ChoDuyet sẵn — gap thật = row 2 (DaDuyet+IsWinner) + row 5/6 dẫn xuất ⇒ **0 migration, 0 endpoint mới, 0 đụng số chính xác**. - **BE:** `PeBudgetAccumulator.ComputePendingAsync` MỚI (pure-add +68/0; `ComputeAsync` 0-diff) — PriorPes `NOT IN {7,99}` · delta-selected `NOT IN {1,7,99}`+IsWinner (GỒM ChoDuyet = gap chính) · delta-submitted `NOT IN {1,7,10,99}` (no-double-count, C6 chứng exact-numbers); `PeBudgetSummaryDto` +5 field append-cuối (frozen→defaults R1-S133 / live→fill); **D4 audit-note** trong `ApplyBudgetSnapshotOnFinalizeAsync` (1 chỗ, `Action=Update` né #49, signature giữ → 5 call-site 0-diff). - **FE 2-app:** types ×2 · PeDetailTabs →`d28eaa16` ×2 (**`sub?: ReactNode` slot-prop** → sub-dòng amber "Tạm tính" row 1/2/5/6 N8-count-đúng-delta + danh sách mã+badge `PurchaseEvaluationPhaseLabel`, N9 no-link tránh 403-S89 + gate `!budgetFrozen`) · PeWorkflowPanel →`bebc0ada` ×2 (banner gate M2 `!readOnly && phase===ChoDuyet` + reminder trong dialog duyệt; Xác nhận 0-diff). - **Decisions D1-D5** (lead chốt theo invest, ⚑ D1 flag anh): nháp list-only KHÔNG cộng tiền · delta row1 làm (TraLai+legacy) · plain-info không hard-block · changelog-in-helper · TuChoi exclude. ## Pipeline (anh chỉ định: "/fable-real invest và review… Sau đó hmw cho Opus 4.8 MAX xử lý") 1. `/fable-real investigator-codebase` — ⚠️ #53 garble return, **sub-file 8-phần 20.7KB cứu trọn** (lần 3 liên tiếp pattern ghi-đĩa-trong-lúc-làm thắng); lead verify **7/7 claim** + 2 errata (path `Dtos/`, hash-value) → spec 3-heading. 2. `/fable-real reviewer` — ⚠️ #53 garble return, sub-file cứu · **GO_WITH_FIXES 0C/2M/9n**: M1 D4-shape đầy đủ (thiếu → hmw tự thêm param = vỡ chính A6) + M2 banner-gate (edge-note "tự ẩn" SAI vs predicate) + N1-N9; **D4-seeder CLEAR** (set trực tiếp, không gọi helper — 0 changelog rác #75-class) → lead áp TRỌN → spec v2. 3. **hmw Opus 4.8 MAX** — INV-2 `wf_58302bd5-b9f` [IMPL-A BE ‖ IMPL-B FE] + INV-3 `wf_97d6a582-b7e` [TEST-C] = **3/3 lane 0-garble, return structured đầy đủ** (lần đầu chuỗi dài sạch trọn); lead re-verify độc lập từng chặng (scope/hash/grep/filter-S133-11-11). 4. Reviewer pre-commit `wf_8bb5abee-657` — **PASS 0C/0M/4-nice-to-have** (tự chạy build+npm ×2+filter 8/8; xác nhận #81-indirect 5/5-qua-helper); lead full-suite độc lập exit-0. 5. Squash §5.0 → push `d4fbced..6664a61` → cicd `wf_f366f38d-498` **GO 5/5 CLEAN**: gate **528 exact-từ-log** · Mig 67 frozen + 89 · bundle ×2 byte-verify 3 marker PRESENT + control 0-hit · smoke 4×200 + PE 401 → lead spot-check độc lập 4/4 hash + marker khớp. ## Lessons - **hmw index sub-file GLOBAL theo taskList** (backend=0, frontend=1) → collision S133 tự hết khi role khác nhau; cùng-role re-invocation vẫn phải đặt tên riêng (đã áp `sub-reviewer-precommit.md`). - **Insertion-only diff** (`grep '^-'` = 0 real-removal) = bằng chứng mạnh nhất cho "thân method/call-site bất động". - **ct=text/html** là SPA-trap discriminator sạch hơn size-heuristic 919B (cicd). - Spec đặt ràng buộc "không đổi X" phải tự kiểm việc-mới lấy đủ nguyên liệu trong X-nguyên-trạng (M1 — reviewer). ## Carry - 🆕 `[carry:uat-s134-luyke]` — UAT script 3 bước trong HANDOFF (sub-dòng amber / banner+dialog / duyệt-A-xong-số-chuyển-chính-xác). - ⚑ D1 nháp-không-cộng-tiền — chờ anh gật giữ hay đổi.