Tiền-đề đối chiếu ĐĨA (không chép plan): `ContractType.cs:5-11` = 1..7 đúng thứ tự `ContractApprovalWorkflowFamily.cs:33-42`; `Layout.tsx:16-29` có sẵn `TYPE_CODE_TO_INT`/`INT_TO_TYPE_CODE`; accordion `:470-485`; `TRANSIENT_QUERY_KEYS :350`; `WorkflowMatrixViewPage.tsx:84-99` khuôn `group`.
## Việc đã làm (7 mục)
(đang chạy)
- **[1] Layout accordion — ưu tiên `ct` + allowlist pathname EXACT.** `fe-user/src/components/Layout.tsx`: thêm const module-level `CT_TYPE_PARAM_PATHS = ['/my-contracts','/contracts/new','/inbox'] as const` (đặt ngay dưới `INT_TO_TYPE_CODE`, kèm chú vì-sao-KHÔNG-`startsWith`); trong `useEffect` accordion, khối `ct` ĐI TRƯỚC `type` (`rawCt !== null && /^[1-7]$/.test(rawCt)` → `INT_TO_TYPE_CODE[Number(rawCt)]` → `setExpandedCtCode` → `return`); nhánh Pe `startsWith('/purchase-evaluations')` GIỮ NGUYÊN VỊ TRÍ ĐẦU của khối `type`; nhánh Ct đổi `else` trần → `else if ((CT_TYPE_PARAM_PATHS as readonly string[]).includes(location.pathname))`. Cast `as readonly string[]` vì tuple `as const` không nhận `.includes(string)` (TS6).
- **[3] Layout comment stale lật.** Khối chú trên regex `Ct_<Code>_<Action>` bỏ câu "HĐ chung 1 bộ workflow V2", viết lại: 7 bộ per-loại `HD-*`@S188 + nguồn BE + phân biệt `type=3`=ApplicableType ⟂ `ct`=danh-tính leaf.
- **[4] TRANSIENT_QUERY_KEYS KHÔNG đụng** — set giữ nguyên 6 phần tử `['id','q','editHeader','page','phase','awId']`. Chỉ THÊM chú CẤM-thêm 3 param danh-tính, đặt **TRƯỚC** dòng `const TRANSIENT_QUERY_KEYS = …` (cố ý: ô C-7 quét `-A6` từ dòng đó xuống ⇒ để chú phía sau sẽ tự tạo dương-giả).
- **[5] WfView `INT_TO_HD_CODE` 7-entry.** `fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx`: const cục-bộ `Record<number,string>` chép TỪNG KÝ TỰ từ `ContractApprovalWorkflowFamily.cs:33-42` (đã MỞ file BE đọc; `ContractType.cs:5-11` xác nhận 1..7 khớp thứ tự `Members`), mỗi dòng chú tên enum nguồn. KHÔNG import từ fe-admin.
- **[7] WfView comment stale thứ 2 lật (X-5).** Khối `:58-60` bỏ "HĐ dùng CHUNG 1 bộ workflow V2", viết lại 7 bộ per-loại + vì sao 7 leaf vẫn chung `type=3`.
## Ô acceptance (kết quả từng ô)
(đang chạy)
> Mọi ô đo SAU khi 7 việc đã land. **Răng của phép đo = DELTA so baseline đo ở đầu file** (ô nào 0→N hoặc 1→0 thì chính baseline là control: nó chứng lệnh grep bắt được cái nó phải bắt, không phải "im vì câm").
| **C-2** (build) | `cd fe-user; npm run build` | EXIT 0 | **EXIT=0**, `✓ built in 12.15s` | ✅ PASS |
**Ô máy: 10/10 PASS.**
⚠️ **Bẫy TỰ-TRÍCH-DẪN ở C-8 vế-2 (đúng lớp bài S188).** Lệnh `-rnF` ra **2 hit**, nhưng hit thứ 2 (`Layout.tsx:496`) là **chính comment tôi vừa viết** đang nhắc lại nguyên văn URL đó, không phải code. Discriminator: bỏ dòng bắt đầu bằng `//` ⇒ còn **1 hit code thật**`Layout.tsx:165` `` return `/contracts/workflow-matrix?type=3&ct=${typeInt}` ``. Ô vẫn PASS theo cả 2 cách đếm, nhưng ghi ra đây để lượt sau đừng đọc "2" thành "có 2 chỗ sinh URL".
ℹ️ **Build warning = PRE-EXISTING, không phải sản phẩm của W1:** `chunk > 500 kB` + `[INEFFECTIVE_DYNAMIC_IMPORT] src/lib/realtime.ts` — cả 2 đã có từ trước (đối chứng: nhật ký vai này ghi đúng 2 warning này ở S167).
### Ô hành-vi — DEFERRED (không dựng dev server theo lệnh giao việc)
| ✅W1(iii) | vòng `ct ∈ 1..7`: ≥1 quy trình đúng họ + 0 dòng khác họ + `ct=1` VẮNG `QT-HD-V2-001` + control `ct=99` KHÔNG lọc | **DEFERRED-TO-LOCAL-VERIFY** — 🔴 ô này là ô DUY NHẤT khoá được mapping int→mã (C-9 chỉ đếm 7 mã distinct, mapping sai vẫn xanh). Bù rủi ro bằng đường khác: mapping chép trực tiếp từ `ContractApprovalWorkflowFamily.cs:33-42` đã MỞ ĐĨA, và `ContractType.cs:5-11` được đo để xác nhận 1..7 đúng thứ tự `Members`. Vẫn CẤM tick tới khi chạy thật. |
### Điều kiện dừng Đ-1..Đ-10: **0 điều kiện chạm**
- Đ-1 eslint: app 47→**47** (không tăng), file-wave 4E→**4E**, 0 ruleId mới ⇒ không chạm. KHÔNG dùng `eslint-disable` chỗ nào.
- Đ-4 scope: chỉ 2 file wave. Cây có 5 file khác đang `M` (`.claude/commands/pause.md`, `tiep.md`, `.session-counter.json`, `docs/HANDOFF.md`, `docs/governance/so-yeu-cau-chu-du-an.md`) — **KHÔNG phải của tôi, KHÔNG add, KHÔNG chạm**.
- Đ-5 neo lệch: 0. Mọi neo plan W1 đo lại khớp đĩa trước khi sửa (accordion `:470-485` · comment `:141-142` · Approved `:152` · `TRANSIENT :350` · WfView `:58-60` + khuôn `group` `:84-99`).
- Đ-8 ranh chờ-anh: không chạm Q3/Q4/Q5/W8/W9.
### DEFERRED (không phải bỏ — là nợ có tên)
1. **3 ô hành-vi W1(i)(ii)(iii) = `DEFERRED-TO-LOCAL-VERIFY`** — lệnh giao việc cấm dựng dev server. 🔴 Trong đó **W1(iii) là ô DUY NHẤT có răng với mapping `int → HD-*`**: C-9 chỉ đếm 7 mã distinct, nếu tôi chép lệch cặp (vd `6: 'HD-NT-DV'`, `7: 'HD-NT-NCC'`) thì C-9 VẪN = 7 và build VẪN xanh. Người chạy local-verify phải làm đúng vòng `ct ∈ 1..7` + control `ct=99`.
2. **Gợi ý cho worker W3** (không phải việc của tôi, chỉ khai để khỏi trùng): chú CẤM-thêm ở trên `TRANSIENT_QUERY_KEYS` đã nêu sẵn cả `pendingMe` ⇒ W3 chỉ cần GIỮ, không phải viết lại; và ô C-7 dùng chung 1 lệnh cho cả 3 param.
3. **Ghi nhận (không hành động):** khối chú "lọc client-side" của nhánh `group` nay nằm TRƯỚC khối `ct` mới trong file WfView, đọc hơi so-le. Không sửa vì (a) đúng nghĩa cả 2 nhánh, (b) chạm thêm = drift ngoài 7 việc được giao (Đ-4).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.