Files
solution-erp/.claude/workflows/runs/2026-08-01-S169-bookend-open/sleep-drafts/implementer-frontend--2026-H2.gist.draft.md
2026-08-03 10:53:28 +07:00

29 KiB
Raw Blame History

implementer-frontend/2026-H2 — gist

distill-gen: 1 source-verbatim: .claude/agent-memory/implementer-frontend/archive/2026-H2.md (14 entry moved-not-cut → 11 cụm [9 đơn + 1 nhóm J1..J5 giữ 5 danh-tính + 1 chỉ-mục FE-M]) pointer-style: substring

TỔNG-HỢP (3-5 ý)

  • Sợi chỉ lặp 5 lần trong 3 phiên (FE-M): tiền-đề đề-bài/lead SAI — K2 việc thật ≈ 1/4 mô tả · K4a 2 tiền-đề sai trong 1 đề bài · K4b lần 3 liên-tiếp · K5 đường dữ-liệu không tồn-tại · K6 spec tự quên 8 designer ⇒ luật rút gọn: đo đĩa TRƯỚC khi gõ, đĩa cãi đề bài thì đĩa thắng — nhưng PHẢI KHAI chỗ cãi.
  • Phép đo phải có control-âm mới gọi là đo: harness đo nhầm cái render bị React vứt — control-âm cũng ra 3 ⇒ phép đo mất khả-năng phân-biệt, trông y như PASS (FE-B); im-vì-đúng ⟂ im-vì-câm (FE-D CA4); 0-hit trần vô nghĩa (FE-C); 2 hash đứng yên = đối chứng dương (FE-D).
  • Điểm-có-RĂNG phải xác định trước khi sửa: writeGuard nằm 2 CHỖ, chỉ :235 (template-literal vào prompt runtime) có răng, :228 là comment (FE-E); containment phải 2 LỚP render + payload — chỉ disabled là containment GIẢ (FE-I); gate FE đổi phải đổi CẢ 2 chỗ, không phải 1 (FE-J4).
  • Hai ranh auto-refuse tự áp của vai (FE-A, {cao}): việc <30 phút TỪ CHỐI nhận (bảo vệ ngân-sách token) + không hạ sàn mirror-SHA × 2 app + npm build × 2 PASS dù bị giục (bảo vệ sàn chất-lượng) — cả hai là quyền tự từ chối, không cần xin phép từng lần.
  • Sai-thầm-lặng phải đổi thành thiếu-nhìn-thấy-được: rỗng-vì-lọc ⟂ rỗng-vì-chưa-có phải khác câu (FE-F); BE /deleted thiếu param group ⇒ không cho UI tuyên nhóm ở màn đã-xoá thay vì hiện số trang nói dối (FE-B).

Entries

🔴 Ràng buộc kế-thừa từ lệnh lead (giữ nguyên khi chốt): TOÀN BỘ file verbatim là nội-dung moved-not-cut đợt drain 08-01 — con-trỏ 1 dòng ở MEMORY.md nhảy bằng tag Ctrl-F ⇒ 14/14 mục giữ danh-tính riêng + NGUYÊN chuỗi tag (mất tag = con-trỏ MEMORY trỏ vào hư-không); mục auto-refuse (FE-A) tag {cao}.

[cao] FE-A — S152 R1: hai ranh giới auto-refuse [s152, auto-refuse-trivial-30min, no-lower-bar-smart-friend]

  • VIỆC: ghi chú lưu-giữ do lead seed on-behalf (M9, hàng đợi memory-ops) — chốt 2 ranh giới vai implementer-frontend tự áp cho chính mình.
  • KẾT-LUẬN: (a) việc <30 phút / vặt (sửa 1 dòng CSS, chỉnh nhãn) = em-main tự làm còn nhanh hơn chi-phí spawn ⇒ TỪ CHỐI nhận, đúng vai, ghi vào role-file; nhận việc vặt là đốt spawn vô ích. (b) KHÔNG hạ chuẩn kiểu "Smart-Friend nể-nang": dù bị giục "làm nhanh" vẫn giữ sàn mirror-SHA × 2 app + npm build × 2 PASS; thiếu 1 trong 2 thì trả lại, không ship.
  • BÀI-HỌC: hai ranh bảo vệ hai thứ khác nhau — (a) ngân-sách token, (b) sàn chất-lượng; cả hai là quyền TỰ TỪ CHỐI của vai, không cần xin phép từng lần.
  • BẤT-NGỜ: một ghi-chú "không làm gì cả" lại là mục đáng giữ nhất nhóm — nó định-nghĩa cái vai này KHÔNG nhận, thứ mọi mục còn lại (toàn việc đã làm) không nói được. → substring:"auto-refuse-trivial-30min"

[cao] FE-B — S166 K4b: phép đo bắt đúng cái render đã bị React vứt [s166, khkk-k4b-group-wire, harness-do-nham-render-bi-vut]

  • VIỆC: nối ?group= vào trang danh sách + trang tạo, kèm vá-3/5/6. Artifact …/sub-implfe-k4b.md.
  • KẾT-LUẬN: BÀI TO NHẤT — suýt kết-luận NGƯỢC: setState gọi TRONG LÚC render khiến React huỷ render đó và render lại với state mới TRƯỚC khi commit; harness bản 1 chạy 1 lượt nên đọc ra phase=3 (giá-trị của render đã bị vứt) — và control-âm cũng ra 3 ⇒ hai nhánh giống hệt ⇒ phép đo mất khả-năng phân-biệt, trông y như PASS. Vá = lặp tới khi state đứng yên → A ra phase=2, control-âm giữ 3. Giải bài chính: override 3 trạng-thái chipPhase: T|null|undefined (undefined = "nghe URL" ≠ null = "user chọn Tất cả") + reset TRONG render theo navKey, KHÔNG dùng useEffect (effect vẽ một lượt dữ-liệu cũ rồi mới sửa = nháy).
  • BÀI-HỌC: mô-phỏng hành-vi framework phải mô-phỏng CẢ vòng đời, không chỉ một lượt gọi hàm. Tiền-đề đề-bài sai lần 3 liên-tiếp: làm đúng nguyên văn ("derive phase từ searchParams thay useState") sẽ giết 6 chip lọc (KpiCard onClick setPhase :153) — hỏng CÂM, build vẫn xanh.
  • BẤT-NGỜ: BE /deleted thiếu tham số group (Controller:61-66 so List:42) ⇒ không lọc được ở client (server đếm total trên tập chưa lọc ⇒ số trang nói dối) ⇒ xử bằng KHÔNG cho UI tuyên nhóm ở màn đã-xoá (đổi sai-thầm-lặng thành thiếu-nhìn-thấy-được) + gắn cờ lane BE; staticMap lệch CÓ CHỦ ĐÍCH (fe-user 6/6 mang group=1, fe-admin 5/6 vì WfView admin trỏ Designer). Bẫy K4b thứ hai (bổ @S170 P3-gate): CreatePage 8 leaf chung MỘT route nên leaf→leaf KHÔNG remount ⇒ preset phải so lastPresetGroup chứ KHÔNG so approvalGroup — so nhầm thì người dùng bấm đổi nhóm bị kéo ngược và ô chọn thành nút chết. K4b bàn giao lead 4 FLAG. → substring:"harness-do-nham-render-bi-vut"

[cao] FE-C — S166 K4a: hai tiền-đề lead sai trong CÙNG một đề bài [s166, khkk-k4a-regex-42-leaf, tien-de-lead-sai-x2]

  • VIỆC: nới regex cho 42 leaf KHKK + gom nhãn nhóm về một nguồn. Artifact …/sub-implfe-k4a.md.
  • KẾT-LUẬN: ① đề bài bảo export KHKK_GROUP_LABELS MỚI, nhưng đĩa ĐÃ CÓ KHKK_APPROVAL_GROUP_LABELS (types/khkk.ts:129, land từ K2, 5 call-site) ⇒ đẻ map thứ 2 chính là phá đúng acceptance-5 (single-source) mà nó phục vụ; đo thêm thấy nhãn BE ≡ `${n}. ${short}` cho 8/8 ⇒ giải bằng DERIVE khkkGroupMenuLabel(n), 0 call-site cũ bị đụng (hardcode lần 2 sẽ ra "N2 - 2. …" đánh số kép ở select). ② comment vá-8 bảo "phải nới regex trước vì sắp gỡ KeHoachKyKet khỏi ẩn-admin", nhưng isAdminHidden:194 = key.startsWith('Ct_') ⇒ KHKK chưa bao giờ bị ẩn ⇒ viết comment theo ĐĨA + gắn cờ "7 nhóm rỗng" (MenuGroup chỉ xét children.length>0, không xét con có resolve được ⇒ header hiện, thân rỗng).
  • BÀI-HỌC: chứng regex bằng new Function() chạy CHÍNH khối text đã ship (indexOf('const khkkMatch') → slice → eval), key sinh từ KhkkGroupNumbers/KhkkLeafActions đọc thẳng MenuKeys.cs ⇒ 42/42 resolve, 0 drop, +3 control-âm (G9→null · action rác→null · Khkk_List nhóm-1-không-infix→null vì chặn ở staticMap trước). Nhãn cũng kèm control-âm (chèn 'x' vào N4 ⇒ phép so phải FLAG) — 0-hit trần là vô nghĩa.
  • BẤT-NGỜ: Khkk_G1 + 6 leaf KHÔNG có infix (S159, cấm đổi kẻo mồ côi permission-row) ⇒ 42 leaf infix chỉ thuộc nhóm 2..8; giữ [1-8] rộng hơn tập seed một nấc là CỐ Ý; Layout 2 app cố ý KHÔNG mirror (user +34 dòng regex · admin +13 dòng comment). → substring:"khkk-k4a-regex-42-leaf"

[cao] FE-D — S166 K5: "chuẩn bị sẵn cho sau" = đổi HÌNH DẠNG, không bịa field [s166, khkk-k5-8-sub-folder]

  • VIỆC: mở 8 ngăn nhóm ở GĐ2 của cây toàn-trình. Artifact …/sub-implfe-k5.md.
  • KẾT-LUẬN: đề bài đòi GĐ3/4 đi qua lines[].contractId pe.contractId; đo 4 nơi đều ÂM (PeListItem 0 hit chữ lines · PurchaseEvaluation.cs:31 chỉ có Guid? ContractId đơn · ContractListItem không có purchaseEvaluationId · Contract.cs 0 khoá ngược). Bằng-chứng đắt nhất là BE TỰ KHAI: CreateContractFromEvaluationFeatures.cs:143-145 pe.ContractId = contracts[0].Id + comment "N HĐ liên-danh truy qua changelog" — endpoint TRẢ contractIds[] (PeDetailTabs.tsx:2186) nhưng chỉ HĐ đầu được ghi ngược ⇒ HĐ thứ 2 trở đi VÔ HÌNH. ⇒ chỉ wire vế làm được: contractIdsOfPackage = new Set<string>() (hợp) thay vì đọc 1 ô, đánh dấu sẵn chỗ cắm nguồn-2 + trích nguyên văn BE; FLAG 2 đường cho lead.
  • BÀI-HỌC: stage.leaves giữ vai danh sách PHẲNG canonical (nguồn đếm duy nhất), groups chỉ chia lại chính nó ⇒ bất-biến tổng là chuyện CẤU TRÚC, không phải kỷ-luật nhớ-cộng-cho-khớp. Hiện đủ 8 ngăn kể cả rỗng = .map trên hằng, KHÔNG .filter; ngăn "(chưa phân nhóm)" chỉ mọc khi thật có phiếu lạc (8 nhóm là khung nghiệp-vụ cố định ⟂ ngăn kia là chỗ chứa bất thường).
  • BẤT-NGỜ: CA4 control-âm tiêm lỗi nhân-đôi ⇒ console.warn NỔ — không có CA4 thì "0 cảnh báo" ở CA1-3 vô nghĩa (im-vì-đúng ⟂ im-vì-câm); 2 hash ĐỨNG YÊN (PipelineTreePanel d70ac315, PePipelineStrip 6fb7337e) dùng làm đối chứng dương cho phép đo SHA. → substring:"khkk-k5-8-sub-folder"

[cao] FE-E — S153 T5: writeGuard là 2 điểm, chỉ một điểm có răng [s153, t5-writeguard-2-diem-235-co-rang]

  • VIỆC: T2 dựng template session-mind-template.md + T5 sửa hmw.js. Lead seed on-behalf @closeout M9 (T2 return mất schema-fail — #53 +1, phải derive-from-body; template VẪN LAND 8.819 B).
  • KẾT-LUẬN: VALID_ROLES 20→21 (sau T10/T11 = 23); 🔴 writeGuard nằm 2 CHỖ: :228 là comment JS (tài-liệu) VÀ :235 là template-literal ĐI VÀO PROMPT của sub. Chỉ sửa :235 ⇒ tài-liệu lệch trong chính file đó; chỉ sửa :228 ⇒ prompt runtime KHÔNG đổi ⇒ vai read-only bị hướng-dẫn như vai được ghi ⇒ Bash-write MD ⇒ mojibake G-009. :235 = điểm có RĂNG. Vùng cấm đo bằng diff: WIDTH_CAP 0 hit · TIER2_EXPECTED_FULL_ID 0 hit.
  • BÀI-HỌC: T2 — ts sống trong HEADING sau em-dash nên 0 dòng key ts: (không phạm rào-2); placeholder <k> trong schema-comment để parser không khớp nhầm; kiểm _SECRET_RES để ví-dụ của rào-3 không tự khớp mẫu của chính nó.
  • BẤT-NGỜ: 2 kẽ báo lead — ① va tên cùng-vai 2 lần gọi (chỉ số i reset mỗi lần gọi ⇒ đợt 2 suýt đè sub-implementer-frontend-1.md của đợt 1) = kẽ CÒN LẠI sau S134; ② node --check trên file thô LUÔN SyntaxError (top-level await) ⇒ acceptance phải là parse-sau-khi-bọc + đối chứng HEAD. → substring:"t5-writeguard-2-diem-235-co-rang"

[vừa] FE-F — S166 K4c: rỗng-vì-lọc phải khác câu với rỗng-vì-chưa-có-gì [s166, khkk-k4c-wfview-loc-nhom, rong-vi-loc-khac-rong-that]

  • VIỆC: lọc trang WfView theo nhóm (đóng FLAG-3 của K4b: ?group= chưa ai tiêu-thụ ⇒ 8 leaf mở 8 trang y hệt). fe-user ONLY, 1 file (+68/5), git diff -- fe-admin RỖNG.
  • KẾT-LUẬN: đo trước 4 thứ, không đoán — ① AwDefinitionDto.code là tên field THẬT (types/approvalWorkflowV2.ts:41, đang render :165) ② trang tải trọn bộ theo type rồi đọc summary.history ⇒ lọc CLIENT-side, KHÔNG thêm trục group vào queryKey (thêm = 8 lần gọi mạng cùng payload + 8 ô cache trùng) ③ DbInitializer.cs:609 code = $"KHKK-N{n}" + :623 IsUserSelectable = true ⇒ 8 workflow thực sự lọt bộ lọc của trang (seed false thì lọc kiểu gì cũng trắng trang) ④ PageHeader bản đang import CÓ actions (repo có ≥2 bản khác chữ ký — lặp bài S37).
  • BÀI-HỌC: chốt chặn KÉP typeInt === 10 && /^[1-8]$/group là khái-niệm riêng của KHKK, type khác hoặc rác thì bỏ qua hoàn toàn (thà hiện đủ còn hơn lọc theo số vô nghĩa ra trang trắng); regex trên chuỗi bắt được "03"Number() sẽ nuốt; lọc giữ đủ VERSION cùng code ("quy trình của nhóm", không phải "1 bản ghi").
  • BẤT-NGỜ: dùng chung một câu cho hai loại rỗng thì user nhóm N5 tưởng cả module chưa cấu hình trong khi 7 nhóm kia đang chạy — cùng họ bài "sai-thầm-lặng → thiếu-nhìn-thấy-được"; chứng 21/21 kèm 2 control-âm (gỡ vị-ngữ lọc ⇒ ra 8 = phép đo phân-biệt được · helper sai khuôn KHKK_N3 ⇒ 0 wf, không âm thầm khớp). → substring:"khkk-k4c-wfview-loc-nhom"

[vừa] FE-G — S166 K6: đếm bằng cách DỰNG LẠI CÂY THẬT rồi chạy chính bộ lọc đã ship [s166, k6-admin-thu-gon, dung-lai-cay-seed-de-dem, route-resolver-khac-menu-row]

  • VIỆC: thu gọn menu admin về đúng vai "nơi cấu-hình". fe-admin ONLY, 1 file (+52/19), fe-user 0-diff.
  • KẾT-LUẬN: spec treo ẩn-số "N = 7 hay 8 tuỳ AwV2_Contract có tồn tại"; đo ra 0 HIT toàn repo ⇒ 2 seed leaf + 8 designer ⇒ chốt N = 1 Dashboard + 4 System-leaf + 2 AwV2 + 8 designer = 15 (spec TỰ QUÊN cộng 8 designer vào công thức của chính nó). Phép đếm: parse 72 tuple literal từ DbInitializer + sinh 128 key từ vòng lặp (hằng đọc thẳng MenuKeys.cs) = 200 node → chạy ADMIN_HIDDEN_KEYS + isAdminHidden + filterForAdmin cắt từ chính file → 166 lá → 15 lá. CONTROL-ÂM: bỏ 'KeHoachKyKet' khỏi Set ⇒ 15→63 (+48 = đúng 8 nhóm × 6 leaf).
  • BÀI-HỌC: filterForAdmin lọc ĐỆ QUY ⇒ ẩn 1 ROOT là cả cây con chết theo ⇒ tập chỉ cần liệt 12 ROOT (thêm Workflows/PeWorkflows vì là CON của System); liệt từng leaf = thừa + phải bảo trì mỗi lần BE thêm key. Vá-14 có 2 lần đảo (S29 ẩn → S57 bỏ ẩn → QĐ7 S164 ẩn lại rộng hơn) ⇒ comment cũ nói NGƯỢC luật đang chạy, gỡ và viết lại kèm câu "cả hai đều từng đúng, mốc sau thắng mốc trước".
  • BẤT-NGỜ: cây dựng lại TỰ KIỂM chính nó — đối chứng "113 key trong MenuKeys.All → 0 key thiếu menu-row (invariant T6)", dựng sai thì chỉ số vỡ ngay; bẫy suýt lẫn: resolvePath:173 CÓ nhánh nhận code 'Contract' nhưng route-resolver có nhánh ≠ menu-row tồn tại. → substring:"k6-admin-thu-gon"

[vừa] FE-H — S164/S165 K2: tiền-đề lead sai, việc thật chỉ ≈ 1/4 mô tả [s164, khkk-nhom-duyet, do-dia-truoc-khi-go, colspan-loi-cam]

  • VIỆC: relaunch p2 sau khi p1 chết vì #53 — nhóm duyệt N1-N8 cho KHKK.
  • KẾT-LUẬN: lead khai CreatePage "mid-wire, 8 khai báo chưa vào JSX" (nghĩa là TS6133 sẽ đỏ); đo git diff TRƯỚC khi gõ thì 8/8 ĐÃ có call-site, Detail cũng đã land ⇒ việc thật ≈ 1/4 mô tả, chỉ ListPage còn dở. p2 sửa đúng 3 điểm: badge N{g} nhét vào ô "Mã kế hoạch" (không đẻ cột — bảng đã cuộn ngang @1366 do cây GĐ 19rem) · thêm cột "Tổng duyệt" (BE trả 0 cho phiếu chưa duyệt ⇒ ép hiển thị kẻo đọc nhầm "đã duyệt 0 đ") · colSpan 7→8 ở HAI chỗ (loading + empty row).
  • BÀI-HỌC: khuôn "WRITE-lane garble ≠ mất code" (S114) đúng thêm một lần: lead đọc transcript dở-dang nên kết-luận theo Ý ĐỊNH đang chạy, không theo đĩa ⇒ viết lại phần đã đúng chính là PHÁ. npm run build = tsc -b && vite build với noUnusedLocals:true ⇒ build LÀ phép thử TS6133 thật, không cần tin IDE (#68).
  • BẤT-NGỜ: quên colSpan là lỗi CÂM cho tới lúc bảng rỗng — chỉ lộ ở trạng-thái ít ai test; SHA-pair 5/5 IDENTICAL với Panel không sửa (hash 2B64144EF6E8 BẰNG baseline) làm đối-chứng dương. → substring:"khkk-nhom-duyet"

[vừa] FE-I — S161 ARC W1+W2+W3đ1: containment 2 lớp và hợp-đồng types [s161, khkk-fe-3-wave, containment-2-lop, types-theo-entity]

  • VIỆC: 3 lượt FE cho KHKK (Designer type-10 · 3 page + types · panel workflow). Mọi lượt đều #53, đĩa cứu trọn.
  • KẾT-LUẬN: W1 — containment phải 2 LỚP render + payload (levelFlagsPayload(e, lock) ép false ở 2/2 call-site; chỉ dùng disabled là containment GIẢ vì copyFromDefinition tuồn state ra); 2 tiền-đề đề-bài sai tự bẻ (FE không có bảng nhãn — nhãn đến từ BE applicableTypeLabel; khuôn type-9 KHÔNG tồn tại ⇒ soi gương Contract:3). W2 — types theo ENTITY khi BE chạy song song; header types = HỢP-ĐỒNG 12 endpoint (reviewer đối chiếu ra 6 chỗ đứt → lead vá). W3đ1 — KhkkWorkflowPanel soi gương PE-panel 1063 dòng theo bảng GIỮ/BỎ tường minh; cây workflow THÔ nên FE tự suy ✓/●/○ từ con-trỏ đôi (StepIndex 0-based vs Level.Order là giá-trị).
  • BÀI-HỌC: hợp-đồng giữa 2 lane phải do LEAD định-nghĩa literal — để mỗi lane tự suy thì đứt ở chỗ không ai nhìn; "place-3 menuKeys SKIP-có-khai (0 consumer)" cho thấy bỏ-qua-có-khai là hành-vi hợp lệ, khác hẳn bỏ sót.
  • BẤT-NGỜ: W2 khai thiếu approverUserId trong opinion, tới W3đ1 mới bổ — lỗ hổng hợp-đồng chỉ lộ ở lượt TIÊU-THỤ, không lộ ở lượt định-nghĩa. → substring:"khkk-fe-3-wave"

[vừa; J4 cao] FE-J1..J5 — 5 mục micro-lesson (khối riêng từng mục, KHÔNG hợp nhất nội-dung)

  • VIỆC: 5 lượt FE 2-app rời nhau, xếp chung để tiện đọc — danh-tính + tag từng mục giữ nguyên:
    • J1 — S134 lũy-kế tạm tính [s134, pe-luyke-tam-tinh, sub-slot-prop]: slot-prop sub?: ReactNode cắm BudgetSharedNumCell:1184 + BudgetColValue:1197 ⇒ chèn sub-dòng amber vào N chỗ render không nhân bản markup; gate showPending = !bs.budgetFrozen && (...); hmw đánh chỉ-số sub-file GLOBAL theo taskList ⇒ hết va tên khi 2 vai KHÁC nhau cùng lần gọi.
    • J2 — S133 badge budget-frozen [s133, budgetfrozen-badge, anchor-by-visible-text]: badge 🔒PeBudgetSummaryTable :1350-1359; 🔴 className header LẶP 2 chỗ (:1350 budget và :1931 winners) ⇒ anchor của Edit PHẢI kèm text nhìn thấy được ("Tổng hợp ngân sách trình ký") mới unique.
    • J3 — S117 radio thứ 5 ProMinMax [s117, prominmax-5th-radio, spread-conditional-before-as-cast]: entry mảng có điều-kiện phải spread TRƯỚC as T[] (né suy-diễn sai); ?? undefined = cách bỏ key chuẩn của axios; Max không cần state riêng (derive từ selectedCandidate) ⇒ 0 chỗ phải reset.
    • J4 {cao} — S116 nhập số ÂM báo giá [s116, sign-toggle-immediate-commit, hasRealSelectedQuote]: 🔴 2 dialog POST commit thẳng form.thanhTien (:2247/:2906, không có nút "Lưu") ⇒ nút đổi dấu phải ghi giá CÓ DẤU NGAY, chỉ lật cờ là MẤT DẤU thầm lặng; parseVnd/formatVndInput :51-52 là hàm dùng chung (chia với ngân sách) nên KHÔNG sửa, bọc Math.abs; gate đổi thành !== 0 (không phải > 0) và 2 gate FE cùng đổi, không phải 1 (missingForApproval:212 + submitChecklist:243 → helper hasRealSelectedQuote).
    • J5 — S113 import v2 + publish [s113, supplier-publish-draft, publish-not-update]: nút "Công bố/Ẩn" gọi POST /suppliers/{id}/publish — KHÔNG qua UpdateSupplier (#73); badge dùng full-class-literal (P14).
  • KẾT-LUẬN: 5 mục = 5 lượt việc rời, mỗi mục 1 tag Ctrl-F sống làm con-trỏ MEMORY.
  • BÀI-HỌC: ba khuôn tái dùng — slot-prop (J1) mở rộng cell dùng chung, anchor theo chữ nhìn thấy (J2) khi className lặp, spread trước cast (J3). J4 dạy cái đắt nhất: form KHÔNG có nút Lưu thì mọi thay đổi hiển-thị phải commit ngay, không thì UI và payload lệch nhau trong im lặng.
  • BẤT-NGỜ: J4 — báo giá nằm ở details[].quotes chứ KHÔNG phải suppliers[].quotes (đi nhầm nhánh là đo nhầm), công thức cũ SUM winnerQuoteTotal chặn oan ca net-zero +100/100=0; J5 — mục "3.d disabled" hoá ra ĐÃ đúng sẵn ⇒ NO change, kèm 1 DEVIATION có khai ("Tải file mẫu" chỉ đặt trong dialog trong khi parent 2.d nhắc thêm nút ở page). → substring J1:"sub-slot-prop" · J2:"anchor-by-visible-text" · J3:"spread-conditional-before-as-cast" · J4:"sign-toggle-immediate-commit" · J5:"publish-not-update"

[cao] FE-M — [CHỈ-MỤC, không thay thế mục nào] sợi chỉ "tiền-đề sai ⇒ đo đĩa trước khi gõ" ×5

  • VIỆC: đánh dấu chỗ lặp để lead viết 1 dòng luật ở L1 thay vì 5 lần kể lại (đề-xuất curator — giá-trị dedup thật của file này).
  • KẾT-LUẬN: K2 (lead khai mid-wire, thật ra 8/8 đã land — việc thật ≈ 1/4) · K4a (2 tiền-đề sai trong 1 đề bài: "chưa có map" thật ra có 5 call-site · "sắp gỡ ẩn" thật ra chưa từng bị ẩn) · K4b (lần 3 liên-tiếp, làm đúng nguyên văn sẽ giết 6 chip) · K5 (đề bài đòi đường dữ-liệu không tồn-tại, đo 4 nơi đều âm) · K6 (spec tự quên 8 designer trong công thức của chính nó).
  • BÀI-HỌC: luật rút gọn: đo đĩa trước khi gõ, và khi đĩa cãi đề bài thì đĩa thắng — nhưng phải KHAI ra chỗ cãi (cả 5 lượt đều khai, nên lead sửa được spec).
  • BẤT-NGỜ: 5 lần sai đều KHÔNG phải lỗi cẩu thả — lead đọc transcript dở-dang hoặc spec viết trước khi code land ⇒ nguyên-nhân ở ĐỘ TRỄ giữa lúc viết đề bài và lúc đọc đĩa, không ở người viết đề bài. → substring:"do-dia-truoc-khi-go"

Phụ-lục token (coverage)

(chép TRỌN token-list section implementer-frontend/2026-H2 của proposal curator — lưới coverage-diff)

  • gotcha#: #82 ("Display-only #82: route+quyền còn nguyên, deep-link vẫn 200, thu gọn = bớt lối đi menu KHÔNG phải thu hồi quyền") · #68 ("build LÀ phép thử TS6133 thật, không cần tin IDE (#68)") · #73 ("POST /suppliers/{id}/publish (KHÔNG qua UpdateSupplier #73)") · #53 (×4: "Relaunch p2 sau p1 chết #53" · "mọi lượt #53, đĩa cứu trọn" · "T2 return mất schema-fail (#53 +1)" · hàm ý ở S161) · G-009 (mojibake — mã governance, không phải gotcha số) · P14 (badge full-class-literal) · 403 S89 (N9 KHÔNG link)
  • surprise (nhãn 🔴/BÀI/BẪY nguyên-văn): "🔴 BÀI TO NHẤT — HARNESS ĐO NHẦM CÁI RENDER BỊ REACT VỨT, suýt kết luận NGƯỢC" · "control-âm cũng ra 3 ⇒ 2 nhánh giống nhau = phép đo mất khả năng phân biệt, trông y như PASS" · "🔴 Tiền-đề đề-bài sai lần 3 liên tiếp (S164→K4a→K4b)" · "🔴 Khuôn S164 'đo đĩa TRƯỚC khi gõ' ăn tiếp 2 lần trong CÙNG 1 đề bài" · "🔴 BÀI CHÍNH — tiền-đề lead SAI, đo git diff TRƯỚC khi gõ … Việc thật ≈ 1/4 mô tả … Viết lại phần đã đúng = phá" · "🔴 BÀI: forward-provision đúng nghĩa = đổi HÌNH DẠNG, KHÔNG bịa field" · "🔴 Bẫy suýt lẫn: resolvePath:173 CÓ nhánh nhận code 'Contract' — nhưng route-resolver có nhánh ≠ menu-row tồn tại" · "(spec tự quên cộng 8 designer vào công thức của chính nó)" · "🔴 Rỗng-vì-lọc ⟂ rỗng-vì-chưa-có-gì phải khác câu" · "🔴 writeGuard là 2 ĐIỂM không phải 1" · "🔴 2 dialog POST commit form.thanhTien THẲNG … chỉ flip cờ = MẤT DẤU thầm lặng" · "🔴 GOTCHA quote ở details[].quotes KHÔNG suppliers[].quotes" · "🔴 Gotcha: className header LẶP 2 chỗ … Edit anchor PHẢI kèm text visible" · "2 hash đứng yên = đối chứng dương" (K5) · "Panel không sửa = đối chứng dương" (K2) · "types 7a99b865 không đổi = đối chứng dương" (K4b) · "im-vì-đúng ⟂ im-vì-câm" (CA4) · "0-hit trần vô nghĩa" (K4a) · "chỉ disabled = containment GIẢ" (W1) · "DEVIATION flagged" (S113) · "3.d disabled ĐÃ đúng SẴN → NO change" (S113) · "2 kẽ báo lead" (S153) · "reviewer đối chiếu ra 6 đứt → lead vá" (W2)
  • guard: writeGuard hmw.js:228 (doc) + :235 (prompt runtime — điểm có RĂNG) · containment 2-LỚP levelFlagsPayload(e, lock) ép false 2/2 call-site · chốt chặn KÉP typeInt === 10 && /^[1-8]$/ · ADMIN_HIDDEN_KEYS + isAdminHidden:194 (key.startsWith('Ct_')) + filterForAdmin (lọc ĐỆ QUY) · noUnusedLocals:true (⇒ build = phép thử TS6133) · gate showPending = !bs.budgetFrozen && (...) · gate !== 0 (thay > 0) + 2 gate missingForApproval:212 / submitChecklist:243hasRealSelectedQuote · preventDefault + stopPropagation trong <summary> · TRANSIENT_QUERY_KEYS:311 (group/filter/view ⇒ giữ active-state) · MenuGroup chỉ xét children.length>0 · CONTROL-ÂM (7 ca: K4a ×3 + nhãn ×1 · K4c ×2 · K5 CA4 · K6 15→63 · K4b control-âm giữ 3) · SHA-pair ×2 app + npm build ×2 PASS (sàn tự áp, S152) · "REFUSE việc <30 min/trivial" (rào nhận việc) · _SECRET_RES (rào-3 tự-không-khớp-mẫu) · placeholder <k> chống parser false-match · "0 dòng key ts:" (không phạm rào-2) · WIDTH_CAP 0 hit + TIER2_EXPECTED_FULL_ID 0 hit (vùng CẤM đo bằng diff)
  • root-cause: ① K4b — "setState gọi trong lúc render ⇒ React huỷ render đó + render lại ngay với state mới TRƯỚC khi commit; harness bản-1 chỉ chạy 1 pass" ② K5 — "pe.ContractId = contracts[0].Id … chỉ HĐ ĐẦU được ghi ngược ⇒ HĐ 2+ vô hình" (CreateContractFromEvaluationFeatures.cs:143-145) ③ S116 — "QuoteDialog setForm({thanhTien}) thay CẢ object → nuốt neg" + "2 dialog POST commit form.thanhTien THẲNG (:2247/:2906, no nút 'Lưu')" ④ S153 — "chỉ sửa :228prompt runtime KHÔNG đổi ⇒ vai read-only bị hướng-dẫn như write-sub ⇒ Bash-write MD ⇒ mojibake G-009" ⑤ K2 — "lead đọc transcript dở-dang → kết luận theo Ý ĐỊNH đang chạy, không theo đĩa" ⑥ K4b — BE /deleted thiếu group ⇒ "server đếm total trên tập chưa lọc → số trang nói dối" ⑦ S153 — "index i reset mỗi invocation ⇒ đợt-2 suýt đè sub-implementer-frontend-1.md của đợt-1" ⑧ S153 — "node --check file thô luôn SyntaxError (top-level await)"
  • file:line: resolvePath:173 · types/approvalWorkflowV2.ts:41 (+ render :165) · DbInitializer.cs:609 + :623 · PeDetailTabs.tsx:2186 · CreateContractFromEvaluationFeatures.cs:143-145 · PurchaseEvaluation.cs:31 · KpiCard onClick setPhase :153 · Controller:61-66 vs List:42 · types/khkk.ts:129 + comment :125-127 · isAdminHidden:194 · TRANSIENT_QUERY_KEYS:311 · hmw.js:228 + :235 · BudgetSharedNumCell:1184 + BudgetColValue:1197 · types fe-user :333 / fe-admin :331 · PeBudgetSummaryTable :1350-1359 + :1931 · PeDetailBundle L433 (anchor admin :488 / user :490) · AddSupplier :2379 + QuoteDialog :2948 · POST :2247 / :2906 · parseVnd/formatVndInput :51-52 · missingForApproval:212 · submitChecklist:243 · MenuKeys.cs (MenuKeys.All 113 key) · Contract.cs (0 khoá ngược) · PeListItem / ContractListItem (0 hit)
  • SHA/hash (đối chứng đo): usePipelineStages 7144eeb7→edff9931 · PipelineStageFolders d449cc8d→bed52f39 · PipelineTreePanel d70ac315 KHÔNG ĐỔI · PePipelineStrip 6fb7337e KHÔNG ĐỔI · List 80ebd79d→fc3944df · Create 677f4ab8→545b4c2f · types 7a99b865 không đổi · types eba649cc→7a99b865 · 5534addb→d28eaa16 · a83a58e1→bebc0ada · 011ee8cf · 617b0aa0 · 3e16dba5 · 78403bd8 · 9947b121 · 2B64144EF6E8 (baseline Panel) · build: index-B0OrpamE 1961mod 620ms · index-DBtbmn5s 1950mod 531ms · index-CZUcTUUg 19.8s / index-BZWvx0Y8 1961mod 10.9s · index-C4F7kHKT 3.6s / index-kv90BBYQ 0.9s · index-B2v0kn5F 1950mod 20.8s / index-84zDBHE- 1961mod 8.2s
  • định-danh run/artifact: runs/2026-07-31-S164-4gd-khkk-fanout/sub-implfe-k6.md · …/sub-implfe-k4c.md · …/sub-implfe-k5.md · …/sub-implfe-k4b.md · …/sub-implfe-k4a.md · …/sub-implfe-k2.md (§1-§5) · runs/2026-07-29-S161-khkk-*/ · .claude/templates/session-mind-template.md (8.819 B) · wf_58302bd5-b9f INV-2.B (S134, engine opus-worker) · chứng: 21/21 (K4c) · 15/15 (K5) · 42/42 resolve + 3 control-âm (K4a) · VALID_ROLES 20→21→23
  • chuỗi tag Ctrl-F 14/14 (con-trỏ MEMORY — PHẢI sống nguyên vẹn): [s166, k6-admin-thu-gon, dung-lai-cay-seed-de-dem, route-resolver-khac-menu-row] · [s166, khkk-k4c-wfview-loc-nhom, rong-vi-loc-khac-rong-that] · [s166, khkk-k5-8-sub-folder] · [s166, khkk-k4b-group-wire, harness-do-nham-render-bi-vut] · [s166, khkk-k4a-regex-42-leaf, tien-de-lead-sai-x2] · [s164, khkk-nhom-duyet, do-dia-truoc-khi-go, colspan-loi-cam] · [s161, khkk-fe-3-wave, containment-2-lop, types-theo-entity] · [s153, t5-writeguard-2-diem-235-co-rang] · [s134, pe-luyke-tam-tinh, sub-slot-prop] · [s133, budgetfrozen-badge, anchor-by-visible-text] · [s117, prominmax-5th-radio, spread-conditional-before-as-cast] · [s116, sign-toggle-immediate-commit, hasRealSelectedQuote] · [s113, supplier-publish-draft, publish-not-update] · [s152, auto-refuse-trivial-30min, no-lower-bar-smart-friend]