wal: flush 20260713T1637

This commit is contained in:
pqhuy1987
2026-07-13 16:37:04 +07:00
parent e5f3c5d70a
commit d3fa073c0c
2 changed files with 12 additions and 4 deletions

View File

@ -10,7 +10,8 @@
- [x] gate — anh Kiệt CHỐT: R1 = CHO HĐ âm (no-op) · R2 = **NỚI guard** `Sum()<=0``All(==0)` (anh hỏi lại: 1-NCC-âm phải gửi được, mâu thuẫn R1 → refine). Implement = FE + 1 điều-kiện BE guard + test. - [x] gate — anh Kiệt CHỐT: R1 = CHO HĐ âm (no-op) · R2 = **NỚI guard** `Sum()<=0``All(==0)` (anh hỏi lại: 1-NCC-âm phải gửi được, mâu thuẫn R1 → refine). Implement = FE + 1 điều-kiện BE guard + test.
- [x] Stage 2 — review (fable-clone 3× reviewer `wf_4824f158-b66`): Lane1 PASS_WITH_FIXES (sign-plumbing baked) · Lane2/3 PASS (mirror clean · budget invariant + #81 safe) - [x] Stage 2 — review (fable-clone 3× reviewer `wf_4824f158-b66`): Lane1 PASS_WITH_FIXES (sign-plumbing baked) · Lane2/3 PASS (mirror clean · budget invariant + #81 safe)
- [x] gate — anh Kiệt CHỐT CEO-threshold = NET (no-op, giữ hiện tại) - [x] gate — anh Kiệt CHỐT CEO-threshold = NET (no-op, giữ hiện tại)
- [!] Stage 3 — review (fable-real, reviewer deep-pass) trên spec CUỐI - [x] Stage 3 — review (fable-real `wf_9648d207-21b`) **#53 garble → em-main-solo gate GO-WITH-FIXES** (Fable UP nhưng cut mid-work 0-verdict; em verify R2-FE trên đĩa → bắt thêm mirror `:235` + iterate-quotes)
- [!] Stage 4 — implement (hmw Opus 4.8 MAX: FE + BE + test)
- [ ] gate — owner-decisions (nếu invest/review lòi ra) - [ ] gate — owner-decisions (nếu invest/review lòi ra)
- [ ] Stage 4 — implement (hmw Opus 4.8 MAX) - [ ] Stage 4 — implement (hmw Opus 4.8 MAX)
- [ ] Stage 5 — verify (test-before "ngân sách giữ nguyên" + build 2-app) - [ ] Stage 5 — verify (test-before "ngân sách giữ nguyên" + build 2-app)
@ -27,4 +28,5 @@
## wf run-id ## wf run-id
- Stage 1 invest: `wf_eaf52972-d18` (task `wslm7eymc`) — 4 lane investigator-codebase, DONE 4/4 clean, HMW-ON, lead Opus 4.8 - Stage 1 invest: `wf_eaf52972-d18` (task `wslm7eymc`) — 4 lane investigator-codebase, DONE 4/4 clean, HMW-ON, lead Opus 4.8
- Stage 2 review: `wf_4824f158-b66` (task `wjhpvoyum`) — 3 lane reviewer, DONE Lane1 PASS_WITH_FIXES + Lane2/3 PASS - Stage 2 review: `wf_4824f158-b66` (task `wjhpvoyum`) — 3 lane reviewer, DONE Lane1 PASS_WITH_FIXES + Lane2/3 PASS
- Stage 3 fable-real: `wf_9648d207-21b` (task `we5wjoxiq`) — single reviewer deep-pass, model:'fable' + effort max (outage→null→fallback Opus) - Stage 3 fable-real: `wf_9648d207-21b` (task `we5wjoxiq`) — single reviewer deep-pass, model:claude-fable-5 (Fable UP); #53 garble → em-main-solo gate GO-WITH-FIXES
- Stage 4 implement: `wf_48834aca-c41` (task `wf609ys7l`) — FE-2app ‖ (BE-guard→tests), Opus 4.8 MAX effort max

View File

@ -20,7 +20,7 @@
3. **Submit gate — AddSupplierDialog** `:2226` `if (detailId && form.thanhTien > 0)``!== 0` (âm tạo quote; rỗng/0 vẫn skip = "chưa báo giá"). Toast `:2239` cùng sửa. 3. **Submit gate — AddSupplierDialog** `:2226` `if (detailId && form.thanhTien > 0)``!== 0` (âm tạo quote; rỗng/0 vẫn skip = "chưa báo giá"). Toast `:2239` cùng sửa.
4. **KHÔNG đụng** `parseVnd`/`formatVndInput` (dùng-chung ô ngân sách cùng file `:51-52`) + **KHÔNG** truyền allowNegative cho ô ngân-sách `thanhTienNganSach:2830` (giữ ≥0). 4. **KHÔNG đụng** `parseVnd`/`formatVndInput` (dùng-chung ô ngân sách cùng file `:51-52`) + **KHÔNG** truyền allowNegative cho ô ngân-sách `thanhTienNganSach:2830` (giữ ≥0).
5. **Submit-guard R2-revised (BE + FE mirror):** BE `PurchaseEvaluationWorkflowService.cs:206` `selectedThanhTien.Sum() <= 0``selectedThanhTien.All(x => x == 0)` (hoặc `!Any(x => x != 0)`). Chặn **CHỈ khi chưa nhập giá nào**; có ≥1 giá thật (âm/dương, kể cả 1 NCC 1 hạng mục âm) → CHO gửi. Message giữ. `Count==0` (chưa chọn NCC) vẫn chặn riêng. 5. **Submit-guard R2-revised (BE + FE mirror):** BE `PurchaseEvaluationWorkflowService.cs:206` `selectedThanhTien.Sum() <= 0``selectedThanhTien.All(x => x == 0)` (hoặc `!Any(x => x != 0)`). Chặn **CHỈ khi chưa nhập giá nào**; có ≥1 giá thật (âm/dương, kể cả 1 NCC 1 hạng mục âm) → CHO gửi. Message giữ. `Count==0` (chưa chọn NCC) vẫn chặn riêng.
- ⚠️ **FE mirror `:201` (Lane-3 nuance):** hiện là `gia <= 0` với `gia`=winnerQuoteTotal=**SUM** — KHÔNG được giữ sum-based (sẽ chặn net-âm mà BE cho → lệch FE/BE). Đổi sang semantics **"không có giá thật nào"** = `!selectedQuotes.some(q => q.thanhTien !== 0)`. Implementer verify FE có list quote đã-chọn tại `:201` (đang render nên có); nếu chỉ có SUM thì phải lấy thêm list. - 🔴 **FE = 2 mirror (em-main gate S116, KHÔNG phải 1):** `:201` (`missingForApproval`, `gia <= 0`) VÀ `:235` (`submitChecklist` label "Giá chào thầu > 0"). CẢ HAI dùng `computeGiaChaoThau``ev.winnerQuoteTotal`=**SUM** (`:75-80`) — SUM KHÔNG phân-biệt all-zero vs net-zero (+100,100=0) → phải **iterate list quote đã-chọn** `ev.suppliers[].quotes`, predicate "có ≥1 selected quote `thanhTien !== 0`". Đổi CẢ `:201` (block khi `!hasReal`) + `:235` (ok khi `hasReal`, label → "Đã nhập giá chào thầu"). Net-zero-có-giá-thật = submittable.
**Semantics giữ:** rỗng/0 = "chưa báo giá" (skip tạo quote); âm = quote thật (≠ rỗng). `formatVndInput(-n)→''` là lý do PHẢI tách magnitude+dấu (không chỉ nới parseVnd). **Semantics giữ:** rỗng/0 = "chưa báo giá" (skip tạo quote); âm = quote thật (≠ rỗng). `formatVndInput(-n)→''` là lý do PHẢI tách magnitude+dấu (không chỉ nới parseVnd).
@ -43,13 +43,19 @@
**Lane-3 test notes:** T1 (budget unchanged) hơi tautological (0 đường ghi budget từ quote) — giữ regression-lock, bề-mặt rò thật = T2. T3 cần seed ≥2 quote TRÁI DẤU/1 winner → mở rộng helper `SeedWinnerWithQuoteAsync` (`PeSubmitGuardAndBypassTests.cs:106-136`, hiện 1 quote/winner); base `:104` không đủ nửa "mixed net>0 submittable". **Lane-3 test notes:** T1 (budget unchanged) hơi tautological (0 đường ghi budget từ quote) — giữ regression-lock, bề-mặt rò thật = T2. T3 cần seed ≥2 quote TRÁI DẤU/1 winner → mở rộng helper `SeedWinnerWithQuoteAsync` (`PeSubmitGuardAndBypassTests.cs:106-136`, hiện 1 quote/winner); base `:104` không đủ nửa "mixed net>0 submittable".
**✅ Owner-confirm CEO-threshold:** anh Kiệt CHỐT dùng **NET** (giữ hiện tại, no-op) — chấp nhận dòng âm có thể kéo phiếu dưới ngưỡng CEO. **✅ Owner-confirm CEO-threshold:** anh Kiệt CHỐT dùng **NET** (giữ hiện tại, no-op) — chấp nhận dòng âm có thể kéo phiếu dưới ngưỡng CEO.
## ✅ Cổng cuối — em-main-solo gate (fable-real #53 garble recovery, S116)
Fable-real deep-pass (`wf_9648d207-21b`, model=`claude-fable-5` — Fable UP) chạy 124K tok/35 tool-call NHƯNG **#53 return-garble** (cut mid-investigation ở CEO-threshold, 0 verdict trong transcript). Per playbook `feedback_agent_return_garble_recover`**em-main-solo gate:**
- **Verdict: GO-WITH-FIXES.** 7 agent (invest 4 + review 3) hội-tụ sạch; sign-plumbing (Lane-1) baked; R-CEO verified trên đĩa (fable-real transcript đọc đúng `winnerQuoteTotal SUM` `:884-889`).
- **1 FIX em-main gate bắt thêm:** R2-revised FE = **2 mirror** (`:201`+`:235`) iterate-quotes-KHÔNG-sum (bake change #5) — điều fable-real chưa kịp soi.
- Còn lại SOUND → **GO implement.**
## ③ Checklist (vai · deliverable · acceptance ĐO ĐƯỢC) ## ③ Checklist (vai · deliverable · acceptance ĐO ĐƯỢC)
| # | Vai | Deliverable | Acceptance đo được | | # | Vai | Deliverable | Acceptance đo được |
|---|---|---|---| |---|---|---|---|
| C1 | implementer-frontend | ± toggle + neg-state cho 2 input quote (`:2365`, `:2917`) × 2 app | Nhập `-5.000.000` → ô hiện `-5.000.000` (KHÔNG trắng); reopen quote âm hiện đúng dấu; SHA `fe-user`==`fe-admin` | | C1 | implementer-frontend | ± toggle + neg-state cho 2 input quote (`:2365`, `:2917`) × 2 app | Nhập `-5.000.000` → ô hiện `-5.000.000` (KHÔNG trắng); reopen quote âm hiện đúng dấu; SHA `fe-user`==`fe-admin` |
| C2 | implementer-frontend | Submit gate `:2226` `>0``!==0` + toast `:2239` × 2 app | Thêm NCC với quote âm → tạo quote (không bị nuốt im lặng); rỗng/0 vẫn "chỉ tạo NCC" | | C2 | implementer-frontend | Submit gate `:2226` `>0``!==0` + toast `:2239` × 2 app | Thêm NCC với quote âm → tạo quote (không bị nuốt im lặng); rỗng/0 vẫn "chỉ tạo NCC" |
| C3 | implementer-frontend | Ô ngân-sách `:2830` GIỮ ≥0 (không allowNegative) | Nhập `-` vào ngân sách hạng mục → bị chặn/không nhận | | C3 | implementer-frontend | Ô ngân-sách `:2830` GIỮ ≥0 (không allowNegative) | Nhập `-` vào ngân sách hạng mục → bị chặn/không nhận |
| C3b | implementer-backend + implementer-frontend | Submit-guard R2-revised: BE `:206` `Sum()<=0``All(==0)` + FE mirror `:201` × 2 app | Phiếu **1 NCC 1 hạng mục âm → GỬI được**; phiếu selected toàn 0 → vẫn chặn "chưa báo giá" | | C3b | implementer-backend + implementer-frontend | Submit-guard R2-revised: BE `:206` `Sum()<=0``All(==0)` + **2 FE mirror** `:201`+`:235` (iterate quotes, KHÔNG sum) × 2 app | Phiếu **1 NCC 1 hạng mục âm → GỬI được**; net-zero-có-giá → gửi được; selected toàn 0 → vẫn chặn "chưa báo giá" |
| C4 | test-specialist | 4 test regression-lock (ngân-sách-giữ-nguyên + winnerTotal + submit-guard + CCM-threshold) | `dotnet test` xanh; test #1 chứng budget bất-biến khi quote âm | | C4 | test-specialist | 4 test regression-lock (ngân-sách-giữ-nguyên + winnerTotal + submit-guard + CCM-threshold) | `dotnet test` xanh; test #1 chứng budget bất-biến khi quote âm |
| C5 | reviewer + cicd | build 2-app + deploy | `npm build` 2-app pass; bundle rotate; prod nhập âm được (anh UAT incognito) | | C5 | reviewer + cicd | build 2-app + deploy | `npm build` 2-app pass; bundle rotate; prod nhập âm được (anh UAT incognito) |