# SUB implementer-frontend-1 — S134 PE lũy-kế TẠM TÍNH (FE 2 app)

> Run: 2026-07-17-S134-pe-luyke-tam-tinh · role implementer-frontend · IMPL-B (items 5-7)
> Ghi-đĩa-trong-lúc-làm (chống #53). Append từng bước.
> ⚠️ NAMING: task top-line nói `sub-implementer-frontend-0.md` NHƯNG RUN-TRACE + subMdPath return nói `-1.md` (×4). Resolve = `-1.md` (khớp return contract). Flag cho em-main reconcile.

## Baseline (git hash-object PRE-edit) — VERIFIED
- PeDetailTabs.tsx ×2 app: `5534addb9a7887c00562a99ab1f52ed4ee77c0ca` IDENTICAL (khớp task) → SHA-mirror protocol: edit fe-user → cp fe-admin → hash verify.
- PeWorkflowPanel.tsx ×2 app: `a83a58e1d8e17ed56660a7061c755d58fa6ad27e` IDENTICAL (khớp task) → same protocol.
- types/purchaseEvaluation.ts: fe-admin `ab4a2ec6` vs fe-user `2bf77367` DIVERGED (KHÔNG mirror, S117 confirmed) → edit RIÊNG từng app, cùng old_string (block PeBudgetSummary content-identical).
- PurchaseEvaluationPhaseLabel exported types:35 · imported PeDetailTabs:29 + PeWorkflowPanel:29 · PurchaseEvaluationPhase.ChoDuyet=10 types:29.
- fmtVnd PeDetailTabs:1002 · cn imported cả 2 file.

## Plan (3 items)
- Item 5 types ×2: +5 field sau budgetFrozen (pendingSubmittedTotal/Count, pendingSelectedTotal/Count, pendingPriorPes[]|null).
- Item 6 PeDetailTabs: +sub `sub?` prop cho BudgetSharedNumCell(:1184)+BudgetColValue(:1197); showPending gate; sub-dòng amber row1/2/5/6 (N8 count tương ứng); block liệt kê pendingPriorPes dưới matrix (:1656).
- Item 7 PeWorkflowPanel: derived vars sau :132; banner amber sau V2-banner (:437); reminder dialog isApproveAction sau Dialog-open (:524, trên price-picker :696). KHÔNG đụng priceMissing:514/footer:522.

## Progress
- [x] Read + ground-truth 6 file + anchors (DONE)
- [x] Item 5 types ×2 (fe-user+fe-admin, same old_string budgetFrozen block) — grep pendingPriorPes = 1/1 ✓
- [x] Item 6 PeDetailTabs — 8 edit fe-user → cp fe-admin → hash `d28eaa16` ×2 IDENTICAL ✓
    - import +type ReactNode; BudgetSharedNumCell+BudgetColValue +sub?:ReactNode prop
    - pending vars + showPending gate + pendingSub helper sau row6
    - row1(:1498) row2(:1503) sub withDetail=true; row5(pro/ccm.r5) row6 sub withDetail=false (N8 count tương ứng)
    - block liệt kê pendingPriorPes dưới matrix (border-t amber, N9 plain+badge phase-color 10/98/1/else)
- [x] Item 7 PeWorkflowPanel — 3 edit fe-user → cp fe-admin → hash `bebc0ada` ×2 IDENTICAL ✓
    - derived: pendingPriors + showPendingBanner(phase===ChoDuyet M2) + pendingPriorsText (sau :132)
    - banner amber sau V2-banner (:437 vùng)
    - reminder dialog isApproveAction && showPendingBanner sau Dialog-open (trên price-picker); KHÔNG đụng disabled Button (B3)
- [x] npm build ×2 — BOTH PASS 0 TS err (tsc -b && vite gate): fe-user 1939mod `index-BVoJX7QA.js` 20.94s · fe-admin 1950mod `index-mcHk0pmo.js` 9.26s. Warn pre-existing @import CSS + >500KB + realtime INEFFECTIVE_DYNAMIC_IMPORT.

## VERIFY FINAL (checklist B1-B4)
- B1 types ×2 (KHÔNG mirror, DIVERGE): grep -c pendingPriorPes = 1/1 ✓. Both build clean.
- B2 PeDetailTabs SHA-mirror: `git hash-object` ×2 = `d28eaa1656e1697f65483e91d6ad8cf381881d65` IDENTICAL ✓ (pre `5534addb`). Frozen phiếu KHÔNG render tạm-tính (showPending = !bs.budgetFrozen && ...) ✓.
- B3 PeWorkflowPanel SHA-mirror: `git hash-object` ×2 = `bebc0ada6afc342f6c22bb2bf12c9f0317d7ade9` IDENTICAL ✓ (pre `a83a58e1`). Disable nút Xác nhận UNTOUCHED — `git diff | grep ^[+-] disabled|priceMissing|shouldPickPrice|transition.isPending` = 0 line ✓.
- B4 diff scope: 6 FE file mine (fe-{admin,user}/{PeDetailTabs,PeWorkflowPanel,types}). 4 Backend file = implementer-backend ∥ (code-disjoint, KHÔNG phải mine). Sub-trace `-1.md` in run-folder.

## NAMING RESOLVED
Run-folder có `sub-implementer-backend-0.md` (∥ agent) + mine `sub-implementer-frontend-1.md` → em-main index fan-out-GLOBAL (backend=0, frontend=1). `-1.md` ĐÚNG; top-line task `-0.md` = stale artifact. Return subMdPath = `-1.md`.

## STATUS: COMPLETE — no ambiguity, full precedent (S133 pattern reused).
