---
name: dryrun-finds-promised-but-unlanded
description: dry-run đi hết đường mới lộ command CHỈ SỐNG TRONG COMMENT — guard chặn thật + đường ghi không tồn tại = feature chết câm mà gate/cicd đều xanh
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 108e4e02-6ced-4d03-b480-a52d66be7af7
  modified: 2026-08-01T12:29:27.891Z
---

**Ca thật S168 (2026-08-01):** trước giờ chạy K8 dry-run, truy vết phát hiện `UpdateContractSigningPlanLineCommand` **chỉ tồn tại trong một dòng comment** của chính file auto-gen (`grep` toàn `src/` + FE = **0 impl · 0 route · 0 call-site**). Trong khi đó submit-guard (vá-5) **chặn thật** dòng `CatalogEntryId=null`. ⇒ **mọi phiếu KHKK tạo sau K2 kẹt Nháp vĩnh viễn**, không đường thoát qua UI lẫn API.

Thứ này **sống sót qua**: 8 wave build · 8 lượt reviewer-gate PASS · 8 lượt cicd verify PASS · 644 test xanh. Không lưới nào bắt vì mỗi lưới hỏi câu của nó (diff có đúng spec? bundle có rotate? test có xanh?) — **không lưới nào đi hết một đường nghiệp-vụ từ đầu đến cuối**.

**Why:** comment hứa việc cho wave sau (*"người soạn gán sau qua `<Tên>Command`"*, *"đường GÁN = K4b"*) là **nợ vô hình**: nó đọc như đã-có-kế-hoạch, và wave được nhắc tên (K4b) **thật sự đã ship — nhưng ship việc KHÁC** (`git show --name-only` chứng: K4b = nối `?group=` sidebar). Hai nửa đều "đúng" theo sổ của mình, mảnh rơi vào khe giữa. Cùng họ với `feedback_absence_looks_like_clean` (vắng-mặt đọc thành ổn) nhưng nguồn khác: đây là **lời hứa trong code** thay cho **vật thật**.

**How to apply:**
1. **Dry-run là PHÉP ĐO, không phải nghi-thức tổng-kết.** Xếp nó TRƯỚC lúc tuyên một chuỗi wave "xong" — nó là lưới duy nhất đi hết đường nghiệp-vụ. Ở S168 nó bắt blocker + 8 thuốc-thử guard mà mọi lưới khác mù.
2. **Comment nêu tên một command/route/wave ⇒ grep tên đó NGAY** (impl + route + call-site), đừng tin comment. Comment mô tả **ý định lúc viết**, không phải trạng-thái hiện tại.
3. **Guard-chặn mà không có đường-ghi tương ứng = chết câm.** Khi thêm guard chặn giá trị null/thiếu, hỏi ngay: *"đường nào ĐANG TỒN TẠI để điền giá trị đó?"* — nếu câu trả lời là một cái tên chưa grep được, guard vừa tạo ra một ngõ cụt.
4. Chạy dry-run **trên fixture TEST riêng**, không trên master/data thật (owner S168 chốt thành luật) — vừa an toàn vừa cho phép chạy lại nhiều lần.

Liên [[feedback_absence_looks_like_clean]] · [[feedback_mechanism_right_data_absent]] · [[feedback_root_cause_over_symptom]].
