# S155→S157 — PE nút XÓA ship prod · điều tra quy trình sau-CEO · UAT Địa điểm

> **Phiên-LOGIC L7**, 4 cửa-sổ vật-lý (2026-07-27 → 07-28), nối bằng `/pause` + `/tiep`.
> Lead: Fable 5 (S156-S157) · State cuối: Mig **68** · 89 bảng · **562 test** · gotcha 83 · counter **31**.
> Con-trỏ durable: `.claude/sessions/session-7/_context-s-7.md` (FLOW 3 entry PAUSE-1..3) · `_mind-s-7.md` (MIND-0..3).

---

## 1. PE — nút XÓA phiếu ở màn duyệt (SHIP PROD, 2 đợt)

**Nguồn:** ảnh chat UAT anh Kiệt FDC. **Owner chốt trong cửa:** cờ `AllowApproverDelete` **per-NGƯỜI** (không per-vai) · màn "Đã xóa" **chỉ xem, không khôi phục** · **vá trọn rồi đẩy** (bác 2 phương án đẩy sớm) · bỏ policy-theo-vai trên đường xóa mới, giữ 3 rào nghiệp vụ.

**Vì sao chia 2 đợt** (anh chốt, có bằng chứng): §F.0 chứng minh quyền xóa **không tới được phiếu đang treo** nếu thiếu lệnh sửa-quy-trình-tại-chỗ ⇒ đợt 1 = NỀN, đợt 2 = phần người dùng chạm.

- Mig **68** `AddPeAllowApproverDelete` — AddColumn trên `ApprovalWorkflowLevel`, **no new table** (89 giữ), reversible Down.
- Commit: `b1bae77` (nền) · `4464a46` (nút xóa + menu 3 mục + màn "Đã xóa") · `f4494cf` (fix menu sáng nhầm).
- **cicd PASS 6/6** — lead **tự đo** @S156 thay vì giao lại `cicd-monitor` (vai đó đã dừng giữa chừng ở cửa trước): endpoint 2/2 → **401** (control bịa ra 404, chứng phép đo có phân biệt) · smoke **8/8** · **D3 giao-tập-ID = 0** (37 phiếu sống ⟂ 9 phiếu xóa, không lẫn) · bundle rotate ×2 app + **4/4 byte-marker** · Run #531 success 5m41s.
- Test **532 → 562** (+30). Chi tiết: `.claude/workflows/runs/2026-07-27-S155-pe-delete-approver/cicd-verify-dot2.md`.

**Lớp lỗi lặp ĐÚNG 4 LẦN trong riêng cửa này** — *cơ-chế đúng, thứ đi qua nó không có*: policy tồn tại nhưng 11/13 vai `CanDelete=0` · endpoint PUT sống nhưng 0 dây FE gọi · policy chặn đúng approver cần dùng · DTO thiếu field FE đang đọc. **Cả 4 đều build sạch + test xanh.** Chốt chặn đã dựng: **T27** (fault-inject xác nhận có răng).

---

## 2. A2 — quy trình SAU khi CEO duyệt (b.7→21) · CHẶN chờ anh

**Nguồn:** PDF sơ đồ *"A. PHÊ DUYỆT GÓI MEP, KẾT CẤU THÉP"* 6 lane × 21 bước. Anh chốt *"đã xong bước thứ 6 tức CEO duyệt rồi, bắt đầu đến Project (Ban Chỉ Huy Công trường)"* ⇒ phạm vi **b.7→21**.

**🔴 Anh ĐẶT TÊN NGHIỆP-VỤ cho khúc 7→12 = "đề xuất giá trị ký kết hợp đồng".** Đây là phát-biểu **MỤC ĐÍCH**, không phải đổi nhãn: đầu ra = **1 CON SỐ có phê duyệt**; b.8-9 (duyệt mẫu / shopdrawing với TVGS) = **căn cứ**, b.10-12 = **chuỗi duyệt chính con số đó** ⇒ nó là **PHIẾU**, không phải thư-mục đính kèm. Hệ quả: Q2 nhánh (c) yếu hẳn, Q6 gần như tự trả lời. Bỏ tên tạm "PostAward" của bản invest.

**Đã chạy:**
- `/fable-real investigator-codebase` (Fable) 2 lượt — lượt 1 **`#53` mất trắng return**, cứu TRỌN từ đĩa; lượt 2 resume cắt-ngắn CLEAN, `sub-invest-bch-1.md` **22.659 B**.
- `/fable-clone reviewer` `wf_1618ae3c-a17` — **4/4 lane sạch, 0 chết**, 35 điểm: verdict `LUNG-LAY 11` · fidelity `CO-VAN-DE 10` · q2 `THIEU-PHUONG-AN 14` (+ thiên-vị-có-hướng) · gaps `4/4 THẬT, 0 dương-giả`.

**Đăng-ký run (Sàn-5 — vá hồi-tố @S158):** detector `governance-detectors.ps1` **C12 raw-engine-bypass** bắt file này
nhắc `wf_` mà **cả file 0 dòng `run=`** ⇒ 3 run-folder của S155-S157 không có nơi đăng-ký BỀN (WAL là sổ ghi-đè, marker
`wf:` bị xoá ngay khi việc xong ⇒ hậu-kiểm cuối phiên soi WAL là **soi chỗ dấu vốn được thiết-kế để biến mất**).
Session-log = append-only ⇒ đây mới là sổ cái. Đăng-ký bù:

```
wf: S155 pe-delete-approver   run=2026-07-27-S155-pe-delete-approver   runId=wf_55f6201f-a52
wf: S156 bch-post-ceo-flow    run=2026-07-27-S156-bch-post-ceo-flow    runId=wf_1618ae3c-a17
wf: S157 ke-hoach-ky-ket-hd   run=2026-07-28-S157-ke-hoach-ky-ket-hd   runId=wf_57af0163-053
```
- **Verdict `LAI` SỐNG:** b.13→21 **TÁI DÙNG** Contract V2 · b.7→12 **DỰNG MỚI**. Đổ ở *nhãn chi-phí* + *cách đặt vấn đề*, không đổ ở lõi.

**Grounding 4 phép (đo, không suy):** `PE.DaDuyet = 7` khớp "xong b.6" · cầu PE→HĐ **CÓ SẴN** (`CreateContractFromEvaluationFeatures.cs`) · `shopdrawing|TVGS|duyệt mẫu` = **0 hit toàn repo** (b.8-9 là đất trắng) · `ContractPhase` **12 giá trị / 7 `[LEGACY]`** — 🔧 lead ghi nhầm "9 phase / 6 LEGACY", **2 vai độc lập bắt được**, máy xác nhận.

**CÒN NỢ trước khi trình anh — 6 việc sửa bản invest** (`review-synthesis.md` §G): vá **1 claim SAI SỰ THẬT** ("hardcoded policy fallback" → thật là `ConflictException:115-116` ⇒ HĐ tạo từ phiếu **KẸT CỨNG `ChoDuyet`**, hỏng CỨNG chứ không degrade êm; gốc: invest **tin skill-doc hơn ĐĨA**, doc stale che luôn lệch display⟂guard) · siết biên `b.14→19` · thêm Q vai-người-TRÌNH · thêm cảnh báo lỗ hổng reject · Q5 thêm phương án (d) `skipToFinal` **ĐÃ WIRE** mà invest bỏ sót · **viết lại Q2** theo 2 trục + 3 số đo cùng đơn-vị lấy từ twin repo.

---

## 3. 🔴🔴 Lỗ hổng an ninh prod — duyệt Hợp đồng (phát hiện @S156, TREO theo lệnh anh)

**KHÔNG liên quan tính năng mới** — gotcha #82 tái phát ở module Contract:

- `ContractWorkflowService.cs:48-66` — nhánh **Reject chạy TRƯỚC MỌI GUARD** (0 kiểm role, 0 kiểm approver, 0 kiểm `fromPhase`), `SaveChanges` + `return` luôn.
- `ContractsController.cs:13` — **`[Authorize]` trần DUY NHẤT** phủ **22 endpoint ghi**.

⇒ **mọi user đăng nhập Từ-chối / Trả-lại được BẤT KỲ hợp đồng nào, kể cả `DaPhatHanh` (terminal)**, kèm xoá `SlaDeadline`. Lead verify **2 tầng độc lập**; đối chứng: PE controller có **3 per-action policy** (bất đối xứng rõ giữa 2 module).

**Trạng thái:** anh chốt 2026-07-28 *"chỗ hợp đồng cứ từ từ nhé"* ⇒ **treo có chủ đích**, không phải bị bỏ quên. Đã tách chip riêng.

---

## 4. S157 — UAT "lấy địa chỉ lên luôn" (SHIP PROD)

**Anh Kiệt 07-28, ảnh chụp form tạo phiếu:** ô **Địa điểm** trống, *"chỗ này lấy địa chỉ lên luôn giúp anh"*.

**🔴 Chẩn đoán: DATA, không phải CODE.** Cơ-chế auto-fill `Project.Location` **đã wire từ S59 và chạy đúng cả 4 tầng** — cột DB → projection `ProjectFeatures.cs:51` → FE type `master.ts:97` → `onChange` SearchableSelect (`PeWorkspaceCreateView.tsx:227` + `PeHeaderForm.tsx:200`, có cả logic không ghi đè khi user đã gõ tay).

Đo prod bằng sqlcmd **trước khi đụng code**:

| Đo | Kết quả |
|---|---|
| BVN01 (dự án trong ảnh) | `Location = NULL` |
| Tổng dự án | 62 |
| **Thiếu Địa điểm** | **57** |
| Có Địa điểm | 5 — CAL01 · MIDEA01 · SAM01 · TLB01 · ZOTE01 |

Đúng 5 dự án đó = đúng 5 dòng có địa chỉ trong file Excel nhập S55. **Nếu viết code auto-fill "mới" thì code sẽ chạy hoàn hảo và ô vẫn trống** — đây là lần **thứ 6** của lớp *cơ-chế đúng, thứ đi qua nó không có*.

**Anh chốt hướng:** *"để người dùng cập nhật Master data rồi sau đó fill ra phiếu, cái nào không có thì không cần fill"* ⇒ **KHÔNG backfill hàng loạt**.

**Vá (`6250f39`):** thêm dòng cảnh báo amber ngay dưới ô Địa điểm, chỉ hiện khi **đã chọn dự án** mà dự án đó **không có `location`** — nói thẳng lý do + trỏ chỗ bổ sung (Danh mục → Dự án → Địa điểm). Lý do làm vậy: ô trống im lặng khiến người dùng tưởng hệ-thống hỏng → đẻ báo lỗi giả (đúng ca vừa xảy ra). 4 file, **SHA256 mirror 2 app IDENTICAL**, npm build 2/2 PASS.

**Deploy verified 2 NGUỒN ĐỘC LẬP:**
- `cicd-monitor` **PASS 9/9** (`cicd-verify-s157-diadiem.md`) — Run #419 success **5m40s**, test gate **562 (45D+517I)** khớp canonical cả 2 thành-phần, bundle rotate 2/2 + `Last-Modified` nằm trong cửa-sổ deploy, byte-marker **2/2 app** (count=2 = đúng 2 chỗ nhúng/app), **control âm**: hash bịa + hash cũ đều rơi về SPA shell 900B `text/html` ⇒ bundle cũ đã **biến mất khỏi đĩa**, deploy ghi đè thật.
- **Lead tự re-curl độc lập, KHỚP TỪNG BYTE:** admin `8-QYcMOg` 1.675.282 B LM 02:44:33Z · eoffice `DptYR4wL` 1.575.513 B LM 02:45:30Z · marker 2/2.

---

## 5. Governance / harness

- **`/tiep` S157** (window 4): Sàn-3 5 tín-hiệu — 3 kêu, cả 3 khớp WAL. `verify:` **5/5 KHỚP, 0 lệch**. Tick counter **30→31 CLEAN**. Thư cross-project `se=0 all=0` (**5/6 repo — `dyd` VẮNG trên máy**, fail-soft khai rõ).
- **`ctx-verifier` @`_tiep-3`** (vai-2 vòng Ctx): `CO-CO — 10 cờ`, return CLEAN. Nặng nhất: trần `_mind` **dư 110 B** ⇒ cửa sau phải nén **≥2 block** (MIND-2 + MIND-3) chứ không phải 1 — carry cũ under-state 2 lần; kèm hở luật *"nén block cũ nhất"* khi block cũ nhất **đã nén rồi**. Cờ **C3 đã vá trong cửa** (header CURRENT STATE còn ghi mốc S153 trong khi số đã bump tới S156).
- **`#53` (return garble) cửa S157 ×1** — `cicd-monitor` **tái phạm đúng dự đoán**: return = mẩu transcript giữa chừng, không phải verdict. **Cứu TRỌN 10.666 B từ đĩa** nhờ lead ép *ghi-từng-mục-trong-lúc-làm* ngay trong prompt. Củng cố datum: **chặn được #53 = ghi-đĩa-trong-lúc-làm, KHÔNG phải prompt-đúng**.
- **Vết lỗi lead @S156:** viết `run.md` **điền SẴN kết-quả cho lượt chạy CHƯA xảy ra** (byte-count + `TOTAL=14 GAP` + verdict = bịa). Tự bắt ngay sau Write, sửa về `[ ]`. Cơ-chế = *quán-tính điền mẫu*; cứu nhờ **thói quen đọc lại thứ vừa Write**, không nhờ trí nhớ ⇒ chốt chặn phải là **luật soi được**.
- **Memory mới:** `.claude/auto-memory/feedback_mechanism_right_data_absent.md` — lớp *cơ-chế đúng / dữ-liệu không có*, nay ×6, kèm luật *"UAT báo không chạy ⇒ ĐO DỮ LIỆU PROD trước"*.

---

## 6. CÒN TREO sang phiên sau

| # | Việc | Chờ ai |
|---|---|---|
| 1 | 6 việc sửa bản invest → trình anh 14 câu → Q1-Q6 | em làm, rồi anh trả lời |
| 2 | Lỗ hổng an ninh duyệt HĐ | anh xếp ưu tiên (*"cứ từ từ"*) |
| 3 | 4 lỗ "cột CÓ mà 0 ai đọc" (L1 cầu PE→HĐ bỏ pin V2 · L2 `CeoApprovalThreshold` 0-consumer phía HĐ · L3 SLA hardcode `AddDays(7)` · L4 `AttachmentPurpose` sai tầng) | em |
| 4 | 22 FLAG governance (42)(43)(44)(E2) — **4 cửa-sổ chưa động** | anh |
| 5 | Trần `_mind` — nén ≥2 block hay nâng `mind_ctx_kb` | anh |
| 6 | `reviewer/MEMORY.md` 19.049 B trên ngưỡng 17.1 KB | em curate |
| 7 | Monthly drift-audit **2026-08-01** | em (session đầu tháng) |
