All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m43s
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>
77 lines
15 KiB
Markdown
77 lines
15 KiB
Markdown
# `.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]"* mà `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>/` có `run.md` mà **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 | có (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 (B1–B6)
|
||
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 là 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 (CÓ 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>/` VÀ 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 có 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 là một phép grep-chuỗi trên chính file này, mà 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 nó. Ghi lại để adap-report nêu với hub: gate grep-chuỗi trên file nó 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 là 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 là chỗ claim cũ 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 mù / 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.
|