# Run — PE multi-NCC per hạng mục (S114)

run-id (B1 invest): `wf_dd49ddc0-f29` | date: 2026-07-12 | session: S114 | branch: main
engine: **fable-clone ensemble** (4-lane investigator-codebase multi-lens) — Opus 4.8 inherit
owner: anh Kiệt (FDC)

## Goal
Cho phép chọn **≥2 NCC-TP trúng thầu vào 1 hạng mục** (PurchaseEvaluationDetail) trong phiếu Duyệt NCC, thay vì hiện tại 1 NCC/hạng mục. Mỗi NCC giữ **1 giá riêng**. Bảng so sánh giá hỗ trợ chọn nhiều NCC.

## taskList snapshot (6-bước anh Kiệt)
- [x] **B1** fable-clone invest ensemble (4-lane inv-cb) → spec — `wf_dd49ddc0-f29` DONE (4/4 clean)
- [x] **B2a** anh Kiệt chốt D1-D4 all recommended (D5 default) — spec LOCKED
- [x] **B2b** fable-clone review ensemble → spec cuối — `wf_1e127f4b-de5` DONE (2/3 clean, lane correctness #53-garble→em-recover; 6 adjustment A1-A6 fold)
- [x] **B3** hmw implement DONE-via-DISK-RECOVER (2 workflow garble #53 return; BE stage-1 `wf_e7ee6abe` + FE/test stage-2 `wf_410896c4` — code trên disk verify: BE compile + 482 test PASS + FE 2-app build + SHA `ae3788e9` + C5 grep 0-sót). ⚠️ FE lane chỉ làm fe-admin → em-main mirror fe-user.
- [x] **B4** fable-clone verify DONE — `wf_14850736-a0a` (2/2 lane CLEAN 0-garble, HỘI TỤ 1 MUST bug: DeleteQuote/DeleteDetail sót re-derive IsWinner → phantom winner HĐ giaTri=0). em-main fix test-before: 2 test RED→GREEN + helper `PeWinnerInvariant` + 3 stale-comment. **486 test PASS**.
- [!] **B5** deploy + commit (cicd verify)
- [ ] **B3** hmw Opus 4.8 MAX implement (BE + FE 2-app + test)
- [ ] **B4** fable-clone reviewer verify implementation
- [ ] **B5** deploy + commit (cicd-monitor verify)
- [ ] **B6** session-end (flush + harvest + eval)

## Lanes B1 (RETURN-only, em-main single-writer synthesize)
- `invest:schema-data` — schema/data-model + migration design
- `invest:be-consumer` — BE read+write consumer audit (CQRS/projection/DTO/kế-thừa-HĐ/budget-compare)
- `invest:fe-consumer` — FE 2-app consumer audit (PeDetailTabs/HangMucCard/QuoteDialog/Bảng so sánh)
- `invest:product-history` — Mig 58/59 multi-winner history + product decision-points

## Synthesis (4-lane hội tụ)
- **3 trục winner:** A `PE.SelectedSupplierId` (single legacy) · B `Supplier.IsWinner` (Mig 58 liên-danh cả gói) · **C `Quote.IsSelected`** (per hạng-mục×NCC, Mig 12 DORMANT). **Feature = trục C**, KHÁC Mig 58 (trục B).
- **Hook `Quote.IsSelected` sẵn từ Mig 12** — persist + echo DTO + seed, mỗi cell có ThanhTien riêng, nhưng 0 consumer tài-chính → storage ≈ 0 migration, chỉ wire + re-key aggregation.
- **Cardinality-change lần 3** (S87 single→multi sót 2 read-site, S88 bắt). 6 BE read-site tài-chính + ~8 FE key off `IsWinner` → grep MỌI consumer.
- 4 lane token: schema 117.9K · be-consumer 130.9K · fe-consumer 100.6K · product-history 148.7K. Tổng 498K, 0 empty/error. Model `claude-opus-4-8` ×4.
- Engine stamp: `[engine: fable-clone-ensemble · Opus-S114]` (em-main harvest @closeout).

## Spec-file
`spec-multi-ncc-per-hangmuc-12-07-2026.md` — Bước 1 kết-tinh (3-mục: đề-bài+ground-truth · cách-implement decision-gated · checklist C1-C6). D1-D5 CHỜ anh Kiệt.
