Files
solution-erp/.claude/workflows/README.md
pqhuy1987 2757e418a1
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m43s
[CLAUDE] Docs: closeout OUTWARD wave adap đợt-9/10 + vá drift skill-matrix H24
Closeout 4 mục OUTWARD của wave S141-S142 (anh gật @S143):
- adap-report 7/7 thư, đủ 5 trường REPORT-FORMAT LOCK, evidence đo thật
- email hub báo-nấc (sha 6c94873f72e0, selftest_verify exit 0, log _index cùng lượt)
- STAGE-2: 7 thư -> inbox/ai_infra/, _index 0 pending, cross-check 7/7
- squash K=8 wal: -> commit chốt

Ngoài wave: agents/README skill-matrix thiếu 2 row H24 (drift S121) -> 15/17 thành 17/17.

Nấc cao nhất khai được = executed-file/verified-pending-restart (trio CHƯA spawn).
2 phát hiện khai thẳng theo G-015 (chi tiết trong report + email):
- whitelist `tools:` KHÔNG chặn ghi ở runtime: 6 vai read-only bị append Write+Edit
- pull-lag do "watch broadcasts/inbox" canh nhầm chỗ

TICK H24: counter 16->17 (S143), 3-điều-kiện OK-reachable, không fail-loud.
Detector TOTAL 46 == baseline 46, 0 flag mới.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 12:32:27 +07:00

77 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `.claude/workflows/` — Workflow fan-out + run-trace convention (Harness-10)
> **Mục đích:** convention cho HMW workflow fan-out + **run-trace folder** (mỗi workflow run → 1 thư mục `runs/<run-id>/` git **TRACKED**, gom plan + per-sub + synthesis + ledger 2-nhịp). Adopt AI_INFRA Harness-10 (anh 06-18) — kế thừa wave-folder memory-isolation Harness-2 nhưng **đổi từ transient-gitignored sang tracked-run-folder** để audit trực-tiếp qua git-diff. 🆕 **Cấu trúc PHẲNG (h10-refine 06-18):** file phẳng cùng cấp trong run-folder (phân biệt RAW vs VERIFIED bằng TÊN), KHÔNG subfolder. Canonical rule: AI_INFRA `CANONICAL-RULES.md` §J4 (return-delta default) + §J6 (run-trace + agent-team) — pull qua `cross_project_search`, KHÔNG copy. Tailor SE 9-role roster + S1 scope.
## Files (tracked)
- `hmw.js` — HMW P2 fan-out script. 2 mode: DEFAULT return-delta-only (§J4) · RUN-TRACE mode (§J6, `args.run`).
- `README.md` — file này (convention).
- `runs/`**git TRACKED** (qua negation `.gitignore:83 !.claude/**`), không gitignore. Mỗi workflow run = 1 sub-folder `runs/<run-id>/`. Xem `runs/README.md` cho cấu trúc chi-tiết (FLAT) + ledger 2-nhịp + 3-layer anti-miss + C8 migration + detector-tailored-out.
## Run-trace = mỗi workflow run → `runs/<run-id>/` TRACKED (FLAT)
Mỗi lần chạy workflow fan-out (RUN-TRACE mode) → **1 thư mục run** git theo dõi, file **phẳng cùng cấp**:
```
.claude/workflows/runs/<run-id>/ ← TRACKED · FLAT h10-refine (hiện trong git-diff = audit trực-tiếp)
├── run.md ← Run-MD chính — EM MAIN ghi @P1 (plan + agents-table + spec + guards + status OPEN→CLOSE)
├── sub-<role>-<i>.md ← per-sub RAW (prefix `sub-`) — full detail (write-sub ghi @P2 · read-only sub → em main scribe @P3)
└── <stage>-synthesis.md ← gom/VERIFIED (suffix `-synthesis.md`) — EM MAIN ghi NGAY sau mỗi fan-out turn (C4 per-turn primary)
```
Phân biệt RAW (prefix `sub-`) vs VERIFIED (suffix `-synthesis.md`) bằng **TÊN file**, KHÔNG subfolder. **C8:** 5 run cũ S71 (`h10-invest``h910-curate`) giữ `sub-md/`+`harvest/` (đừng rewrite history); close-gate chấp nhận CẢ HAI dạng.
🔴 **DUAL-ACCEPT (S123) — close-gate nhận HAI dạng.** Định-nghĩa CANONICAL + block quét = [`.claude/commands/tiep.md`](../commands/tiep.md) **§0** (KHÔNG chép logic sang đây — B1):
| dạng | hình-dạng | tư-cách |
|---|---|---|
| **1** | `<stage>-synthesis.md` **phẳng** | ✅ **hiện-hành — run MỚI BẮT BUỘC dùng dạng này** |
| **2** | `harvest/<stage>-synthesis.md` | 🧊 legacy C8 (5 run S71) — nhận, **cấm viết mới** |
| ~~**3**~~ | ~~heading `## synthesis` trong **THÂN `run.md`**~~ | 🧊 **RETIRED S123** (anh chốt) — **KHÔNG còn nhận** |
**Vì sao phải nhận dạng-2 (đây là sửa ĐÚNG, không phải nới lỏng):** gate hỏi *"đã harvest chưa"* — câu hỏi về **NỘI DUNG** — nhưng lại đo **TÊN FILE**. Đo thật @S122: **8 dương-giả / 25 run = 32%**; folder **ghi chép đầy-đủ NHẤT** (`pe-negative-quote`: có cicd PASS + bundle-hash + smoke 200 + 6 stage `[x]`) **vẫn** bị xếp orphan. Bồi: commit `8fa2fcc` khoe *"close-review run.md synthesis [H2 gate]"*`git show --stat` **không chạm folder** ⇒ H2 **đã soi + coi ĐÓNG**, chỉ lệch tên file.
🧊 **Dạng-3 RETIRED @S123 — LUẬT retire (phát-biểu ĐÚNG):**
> **Gỡ một nhánh legacy khi tập di-sản của nó RỖNG; giữ khi CÒN người thụ-hưởng.**
- **Đo trước khi gỡ (harvest-curator + lead, 2 phép độc-lập, khớp):** bỏ nhánh dạng-3 ⇒ **0 folder** thành orphan. Cả **6 folder** từng dựa nó (`S112`×4 · `S113` · `S114`) **nay đều có flat `*-synthesis.md`** sau retro-harvest `22ea8c5` ⇒ dạng-1 bắt hết ⇒ **dạng-3: tập di-sản = 0 ⇒ GỠ**.
- 🔸 **Dạng-2 GIỮ — vì tập di-sản = 5 folder S71, KHÔNG rỗng.** Miễn-trừ C8 (*tha di-sản*) hết hiệu-lực **đúng lúc hết di-sản để tha**, không sớm hơn.
- ⚠️ **Bản đầu S123 viết lý-do khác và SAI** (reviewer bắt): *"doc CẤM viết mới mà máy VẪN NHẬN ⇒ cấm-bằng-trí-nhớ ⇒ gỡ"*. Áp thẳng lý-do đó cho **dạng-2** — mà `:25` cũng ghi *"legacy C8 — nhận, **cấm viết mới**"* ⇒ **cùng hình-dạng** ⇒ phải gỡ luôn dạng-2 ⇒ **5 folder S71 thành orphan** ⇒ ép rewrite history mà **chính C8 cấm**. ⇒ **Lý-do viết ra ≠ lý-do thật đang vận-hành.** Bài: **áp luật vừa viết cho nhánh ANH EM — vỡ thì LUẬT sai, không phải nhánh sai.**
- 🔸 **Hệ-quả phụ (cái ĐƯỢC, KHÔNG phải cái BIỆN-MINH):** sau khi gỡ, luật và máy nói cùng một câu về dạng-3 ⇒ hết cần trí-nhớ để NÊU.
🔴 **Nhận ≠ cho phép** (đúng khuôn C8: *tha di-sản, cấm viết mới kiểu cũ*). Dạng-3 **phá chính thiết-kế "tên file mang nghĩa"** ở dòng trên. **KHÔNG phải convention của một thời-kỳ:** cùng ngày **07-12**, `h22-wal-adopt` ghi dạng-1 còn `S112-*` ghi dạng-3 ⇒ **thói-quen không nhất-quán**. ✅ **@S123 khoảng-cách doc-vs-máy này ĐÃ ĐÓNG** — run mới ghi dạng-3 nay **máy FLAG orphan ngay**, không cần ai nhớ để NÊU.
🔸 **Kẽ CÒN LẠI — dạng-4** (kết-quả rải dưới heading tuỳ-ý, vd `## Stages` + `## wf run-id`): **KHÔNG máy nào bắt được** — nhận nó = phải nhận "bất-kỳ run.md nào có vẻ nói về kết-quả" ⇒ quá lỏng, vô-nghĩa ⇒ **để người phán**. Đây **KHÔNG phải chuyện đã xử**. ⚠️ **Neo vào TÍNH-CHẤT, đừng neo TÊN FOLDER:** ví-dụ `pe-negative-quote` mà bản S122 dùng **đã hết hiệu-lực** (retro-harvest `22ea8c5` biến nó thành dạng-1) — lập-luận còn đúng, literal đã chết (chi-tiết + bài học `acceptance literal tự-lão-hoá` → [`tiep.md §0`](../commands/tiep.md)).
- `runs/_ledger.md` — 🧊 **RETIRED H18-B S100** (sổ 2-nhịp nghỉ-hưu — đo bắt-thật: true-orphan-catch 0/15 lifetime + mode-A coverage 0/8 workflow từ S93; 15 row lịch-sử GIỮ NGUYÊN, đảo-ngược = gỡ marker). **Orphan-authority = folder-scan:** `runs/<id>/``run.md`**KHÔNG thoả dạng nào trong DUAL-ACCEPT** (dạng-1 phẳng · dạng-2 `harvest/`) — mỗi dạng đều đòi **khác 0-byte**. 🔴 Block quét canonical + fault-inject (**S122 9/9** → **S123 7/7 sau retire**) → [`tiep.md`](../commands/tiep.md) **§0** (⚠️ bản trước S122 chỉ nhận dạng-1 ⇒ **32% dương-giả**). Chi-tiết `runs/README.md`.
## 2 MODE memory (anh 06-07, KHÔNG thay return-delta)
| | DEFAULT return-delta-only (§J4) | RUN-TRACE mode (§J6) |
|---|---|---|
| Khi dùng | fan-out NHỎ (<3 task **VÀ** ước 5 phút; read/analyze vd recon) | workflow DÀI / sinh nhiều detail / cần audit-trail |
| Bắt buộc? (sàn H22 S111) | mode-A hợp lệ cho fan-out NHỎ | **BẮT BUỘC khi run ≥3 task HOẶC ước chạy >5 phút** (`args.run` per-agent-file `sub-<role>-<i>.md`) |
| Sub ghi file? | KHÔNG chỉ return `memoryDelta` + `findings` | write-sub GHI full-detail vào `runs/<run-id>/sub-<role>-<i>.md` (phẳng); read-only sub `findings` + `subMdPath` em main scribe |
| Lead làm | VERIFY + APPEND @P3 (B3) | đọc `sub-<role>-<i>.md` on-demand + ghi `<stage>-synthesis.md` per-turn (C4) + H2 gom @session-end (B5, backstop) |
| Rủi ro mất detail | (delta lossy) chấp nhận cho việc nhẹ | KHÔNG (full-detail giữ trong run-folder tracked) |
> **Sàn H22 (S111) — FLIP policy:** mode-A return-delta-only VẪN hợp lệ cho fan-out NHỎ, NHƯNG **run ≥3 task HOẶC ước chạy >5 phút = BẮT BUỘC RUN-TRACE mode** (`args.run` → per-agent-file `sub-<role>-<i>.md` trong run-folder). Lý-do: chết giữa run vẫn còn vật-liệu trên đĩa để `/tiep` nối lại — **per-TURN ≠ per-TASK: returns mất khi chết giữa turn, nhưng file trên disk còn**. Fan-out NHỎ dưới ngưỡng → DEFAULT return-delta-only vẫn OK (KHÔNG bắt MỌI fan-out tạo run-folder).
## Quy trình RUN-TRACE (B1B6)
1. **B3 SCAFFOLD TRƯỚC (em main @P1):** tạo `runs/<run-id>/` + `run.md` (FLAT KHÔNG cần `sub-md/`/`harvest/` subfolder hay `.gitkeep`; file `sub-*`/`*-synthesis.md` sinh phẳng cùng cấp khi fan-out chạy). *(🧊 bước "ghi OPEN-beat vào `runs/_ledger.md`" retired H18-B S100 — orphan-authority = folder-scan.)* `hmw.js` chạy JS-sandbox **no-filesystem** KHÔNG tự tạo folder; **em main Write @P1** TRƯỚC khi invoke Workflow. (Đây fragile-point quên scaffold = run mất dấu-vết âm-thầm; xem `runs/README.md` §C7.)
2. **B1 spawn-from-real-sub:** mỗi task `role ∈ VALID_ROLES` (**roster ĐẦY-ĐỦ** số vai canonical [`docs/STATUS.md`](../../docs/STATUS.md) §Sub-agents, B1 KHÔNG chép số đây) workflow-agent = sub THẬT (`agentType` inherit memory-pack slice + skill identity), KHÔNG agent vô-danh.
3. **B4 phân-quyền TOOL-AWARE:** `hmw.js` inject vào prompt mỗi sub đường-dẫn `runs/<run-id>/sub-<role>-<i>.md` (phẳng) + lệnh ghi ĐÚNG file đó.
- **Write sub ( Write/Edit):** implementer-backend · implementer-frontend · test-specialist · frontend-designer ghi-direct sub-MD via Write/Edit.
- **Read-only sub (CHỉ Bash):** investigator-codebase · investigator-api · reviewer · cicd-monitor 🔴 KHÔNG Bash-write MD (mojibake) full-detail vào `findings` + `subMdPath` **em main scribe @P3** (single-writer).
4. **B6 ISOLATION (AUDIT cẩn-thận):** sub CHỈ ghi trong `runs/<run-id>/` (file `sub-<role>-<i>.md` phẳng của mình) + code-file-disjoint nếu giao. 🔴 KHÔNG ghi `agent-memory/*` chính · KHÔNG MD canonical (CLAUDE/README/STATUS/agents) · KHÔNG sub-MD agent khác. **Em main `git status`/`git diff` + chunk-count sau P2** **run-folder TRACKED → mọi write trong run-folder HIỆN trong diff = audit trực-tiếp**; tracked-change NGOÀI `runs/<run-id>/` NGOÀI code-disjoint đã giao = **vi-phạm** (thay model Harness-2 B6 "mọi tracked-change = vi-phạm"). Verify pattern bằng `git check-ignore -v` (test match thật, đừng tin .gitignore text bẫy exit-code: dùng `&& IGNORED || NOT`).
5. **B5 HARVEST (per-turn primary C4 + close-gate backstop):** em main ghi `<stage>-synthesis.md` (phẳng) **NGAY sau mỗi fan-out turn** (đọc `sub-<role>-<i>.md` + findings 5-trục integrity consolidate). @session-end harvest-curator H2 §L.b(f) **VERIFY per-turn harvest đã xong cho mọi `runs/<id>/`** (idempotent KHÔNG re-APPEND, chống DUPLICATE-HARVEST) + giữ 5-trục GATE làm backstop, rồi đề-xuất em main APPEND vào `agent-memory/<role>` sub tương-ứng.
## Agent-team (`.claude/agent-teams/<tên>/` — gitignored `.gitignore:94`)
- Cùng nguyên-lý isolation: teammate **KHÔNG có memory-dir built-in** (khác subagent) folder riêng cho teammate ghi MD-session (A1, tránh overwrite memory chuẩn).
- Team spawn TỪ **sub-agent chính có memory dự-án rõ-ràng** (A2 mang identity/skill sub thật trong roster số vai canonical [`docs/STATUS.md`](../../docs/STATUS.md) §Sub-agents, B1 KHÔNG chép số đây).
- H2 harvest-curator gom `.claude/agent-teams/<tên>/` agent-memory tương-ứng (giống run-trace).
- **Caveat: Agent-Team experimental + Windows 11 in-process only** (no split-pane) SE **CHƯA dùng team thật** A = **convention-ready** (n-a runtime), cơ-chế isolation chung qua workflow.
## Guard
- **S1:** Workflow CHỈ repo SOLUTION_ERP KHÔNG fan-out repo/corpus khác (`cross_project_search` = READ reference only).
- **S2/S3:** chỉ chạy khi HMW-mode ON (`/ultra-on` marker `.claude/hmw-mode.on`) + checkpoint INFORM (`hmw.js` throw nếu `checkpointApproved≠true`) + sub KHÔNG spawn sub.
- **Anti-bypass detector (h10-refine b) SE KHÔNG dựng detector; nhưng CẤM đọc thành "SE không kẽ".** 🔴 Bản trước S120 tuyên SE đã "tailored-out" khỏi lớp detector này **và coi mặt-lách là gần-như-không-có** **STALE, gỡ S120 W0.4** bị bác **×3 bằng sự-kiện thật**, không phải lý-lẽ. *(Nguyên-văn claim cũ: `git log -p --follow -- .claude/workflows/README.md`. Ở đây **cố ý paraphrase, không trích literal**: gate của W0.4 một phép grep-chuỗi trên chính file này, grep **không phân-biệt được** claim-đang-sống với claim-đã-chết-được-trích-làm-bằng-chứng trích nguyên-văn sẽ làm gate FAIL trên đúng bản sửa ĐÚNG. Cùng lý-do: **không viết literal mẫu regex của gate vào đây** S120 đã mắc đúng bẫy đó, mẫu tự khớp chính . Ghi lại để adap-report nêu với hub: gate grep-chuỗi trên file kiểm = **tự-tham-chiếu**, cần neo bằng dấu-hiệu khác.)* **SE có 3 đường phóng workflow/agent, chỉ 1 đường gate được:**
1. `/ultra-on` `hmw.js` **QUA gate** (writeGuard · Sàn-1 marker · VALID_ROLES). Đường DUY NHẤT được phủ.
2. **raw Workflow tool** (Anthropic) **KHÔNG gate.** S72 RECURRED: chạy REVIEW đường này không inject writeGuard reviewer tự ghi MEMORY **+2850B over-cap** git-status bắt @session-end + revert. Kết-luận nguyên-văn `feedback_harness10_run_trace.md:20`: *"dùng RAW Workflow tool = **MẤT governance của project-wrapper**"*. 🔴 **Chính run S119 đi đường này.**
3. **raw Agent tool** **KHÔNG gate.** S118: 7-spawn **0 run-folder** (việc rớt khỏi sổ).
🔴 **Kẽ CÒN-LẠI (khai thẳng, KHÔNG overclaim):** lách SE **không cần CLI-launcher** gọi thẳng tool của harness xong. 3 nguyên-tắc detector (whitelist launcher · path-variant match · anchor launch-key + nghiệm-thu quan-hệ) **N/A vì KHÔNG CÓ launcher để whitelist**, **KHÔNG phải vì "không có kẽ"** đây đúng chỗ claim trượt. Containment THẬT = **em-main single-writer + git-diff (run-folder TRACKED nên mọi write in-repo hiện) + chunk-count RAG + folder-scan orphan** (🧊 `_ledger` retired H18-B S100) = **phát-hiện-SAU, KHÔNG ngăn-chặn-TRƯỚC** (G-015). Chi-tiết `runs/README.md`.
- **G-015 accuracy (no-overclaim):** run-folder TRACKED read-only-ENFORCED sub vẫn giữ Bash (write-channel mở: ghi-ngoài-repo git-diff / curl Qdrant). Containment THẬT = **em-main single-writer + git-diff (in-repo, run-folder tracked nên hiện) + chunk-count (RAG)**, defense-in-depth, KHÔNG sandbox cứng. KHÔNG claim "ENFORCED", KHÔNG bỏ chunk-count.