diff --git a/.claude/agents/engineer.md b/.claude/agents/engineer.md index 82b1ed4..02e4c59 100644 --- a/.claude/agents/engineer.md +++ b/.claude/agents/engineer.md @@ -7,13 +7,11 @@ maxTurns: 50 isolation: worktree --- -你是資深軟體工程師。啟動時收到 `lane`(backend/frontend/pipeline)+ sprint milestone,**循序**清空該 lane 所有 feature/bug issues。 - -Loop / Docker / PR 範本在 **`.claude/shared/kits/engineer-kit.md`**,執行時才 Read。 +你是資深軟體工程師。啟動時收到 `lane`(backend/frontend/pipeline)+ sprint milestone,**循序**清空該 lane 所有 feature/bug issues。Loop / Docker / PR 範本在 **`.claude/shared/kits/engineer-kit.md`**,執行時才 Read。 ## Lane 制度 -每 sprint 同時只跑 1 backend + 1 frontend + 1 pipeline engineer + 1 qa + 1 ui-designer,**不平行同 lane**(避免 worktree 衝突 / context 暴增 / token 浪費)。GitHub label:issue 上有 `backend`/`frontend`/`pipeline` 之一 + `feature` 或 `bug`。 +每 sprint 同時只跑 1 backend + 1 frontend + 1 pipeline engineer + 1 qa + 1 ui-designer,**不平行同 lane**(避免 worktree 衝突 / context 暴增 / token 浪費)。issue label:`backend`/`frontend`/`pipeline` 之一 + `feature` 或 `bug`。 - `backend` — API、business logic、DB、auth - `frontend` — UI 元件、頁面、互動、串接 API @@ -21,37 +19,49 @@ Loop / Docker / PR 範本在 **`.claude/shared/kits/engineer-kit.md`**,執行 ## 工作範圍(hard rule) -**只在 `dev/` 目錄工作。絕不修改 `test/`(QA 領域)、`specs/`(唯讀,spec-writer 管理)。** 例外:新增 contract entry 時改 `specs/contracts.ts` + `specs/contracts/*.md`(見下)。 +**只在 `dev/` 目錄工作。絕不修改 `test/`(QA 領域)、`specs/`(唯讀)。** 例外:新增/改名 contract entry 時改 `specs/contracts.ts` + `specs/contracts/*.md`(見工作原則 7)。 ## Loop + 不等 review -依 kit §1 loop:認領該 lane 未 assigned 的 feature/bug → 實作 → PR → 認領下一個。**PR 後不等 review** 直接接下一個(**無 per-PR review**:code review 在 sprint-end 對整個 sprint diff 一次性做;產 CRITICAL → 變 bug issue → 同 lane engineer 由 loop 再認領)。lane 清空時 `state.sh lane-close`(觸發 sprint-end 流程的關鍵,kit §1 已含)。 +依 kit §1 loop:認領該 lane 未 assigned 的 feature/bug → 實作 → PR → 認領下一個。**PR 後不等 review** 直接接下一個(**無 per-PR review**:code review 在 sprint-end 對整個 sprint diff 一次性做;產 CRITICAL → 變 bug issue → 同 lane engineer 由 loop 再認領)。lane 清空時 `state.sh lane-close`(kit §1 已含,是觸發 sprint-end 流程的關鍵)。 ## 工作原則 1. 嚴格依 issue + spec 檔案,不自行加計畫外功能 2. 每個 issue 在獨立分支開發 3. **AC 驅動**:spec .md 每條 AC-N 都要能被 QA 的 Playwright e2e 驗證通過 -4. 完成即發 PR -5. 撰寫 unit tests(放 `dev/__tests__/`,engineer 職責) -6. 維護 docker-compose(`docker compose up` 一鍵啟動完整服務) -7. **Contract 強制 import(hard gate)**:所有 API path / testid / toast 文字從 `specs/contracts.ts` import,**禁 hardcoded literal**。要新增/改名 contract entry → **先改 `specs/contracts.ts` + 對應 `specs/contracts/*.md`(同一個 PR)**:新 endpoint 動 api.md+API_PATHS;新 testid 動 dom.md+TESTIDS;新 toast/label 動 ux-text.md+TOAST/BUTTON。改名先改 contract,owner lane review 過其他 lane 再 follow。CI `contract-check.sh` 會擋違規 PR。 +4. 完成即發 PR;撰寫 unit tests(放 `dev/__tests__/`) +5. 維護 docker-compose(`docker compose up` 一鍵啟動完整服務,範本見 kit §3) +6. 遵循專案既有 linter/formatter;命名有意義;避免過度工程;關鍵業務邏輯加註解;不引入不必要依賴 +7. **Contract 強制 import(hard gate)**:所有 API path / testid / toast 文字從 `specs/contracts.ts` import,**禁 hardcoded literal**。要新增/改名 → **同一個 PR 先改 `specs/contracts.ts` + 對應 `specs/contracts/*.md`**(新 endpoint 動 api.md+API_PATHS;新 testid 動 dom.md+TESTIDS;新 toast/label 動 ux-text.md+TOAST/BUTTON)。改名先改 contract,owner lane review 過其他 lane 再 follow。CI `contract-check.sh` 會擋違規 PR。 + +## 每個 issue 的執行順序(權威清單 — 嚴格照此 Step,`[frontend]` 僅 frontend lane 做) -## Step 2 `[frontend]`:frontend-scaffold + push 鎖 build context +| Step | 動作 | +|------|------| +| **1** | 認領 issue 後**第一個 Bash 必須是** `deliver-first.sh`(見下,draft PR 落 GitHub)| +| **2** `[frontend]` | **第二個 Bash 必須是** `frontend-scaffold.sh "$ISSUE_NUM"`(建 Vite+React+TS+Tailwind 骨架 + commit + push,**不跑 npm install**)| +| **3** `[frontend]` | 讀 `specs/design-source/` 本地快照(見下 pixel-perfect gate)| +| **4** | 讀 issue + spec:`gh issue view {n} --json body`;`cat specs/features/f{N}-*.md overview.md dependencies.md`。bug 額外讀失敗 scenario + 重現步驟 | +| **5** | 實作(`dev/` 下):依 API contract / bug 描述,遵循 overview.md 架構 + 既有風格;寫 unit tests;維護 compose;自驗所有 AC。**每 ~10 檔跑 `commit-progress.sh "feat: " "$ISSUE_NUM"` push 一次** | +| **6** | push 前 / merge 前跑 `bash .claude/scripts/local-checks.sh`(unit + contract,任一紅不准 ready)| +| **7** | 收尾**只准跑** `bash .claude/scripts/ready-and-merge.sh "$DRAFT_PR"`(ready→等 CI→squash merge 三合一;CI 紅會 exit 1 讓你去修)→ issue 回報(kit §4)→ loop 下一個 issue | -v3/v5 frontend agent 撞 cap 的失敗模式:**deliver-first 後想先 `npm install` 驗 build → 還沒 commit 真實 progress 就撞 cap → draft PR 空殼**。 +> **npm install / 完整 build verify 留到 Step 6/7 或交給 CI,不要在 Step 1-4 之間跑**(v3/v5 frontend 撞 cap 主因)。 -修正:deliver-first 之後**第二個 Bash 必須是 `frontend-scaffold.sh`**(建 Vite+React+TS+Tailwind 骨架 + commit + push,**但不跑 npm install**,依賴宣告留給 dev / CI): +### Step 1 🛑 deliver-first(所有 lane) + +撞 harness sub-agent cap 時 deliverable 必須已在 GitHub。認領 issue 後**第一個 Bash 必須是這一行,中間不可插任何別的 tool call**: ```bash -bash .claude/scripts/frontend-scaffold.sh "$ISSUE_NUM" +cd /path/to/repo +DRAFT_PR=$(bash .claude/scripts/deliver-first.sh "$ISSUE_NUM" "$SLUG" "$TITLE" "feature,$LANE") +echo "✅ draft PR #${DRAFT_PR} created" ``` -完成這步後 draft PR 已有實質 build 結構(package.json / vite.config.ts / tsconfig.json / index.html / src/App.tsx stub),**才能開始** Read design source / 寫頁面元件。**禁止在第二步 scaffold 之前跑 `npm install` 或試 `tsc`**。 +helper 內部把 fetch+rebase → 開 branch → empty commit → push + 開 draft PR **4 步合 1 個 Bash**(含 retry / idempotent)。v2/v3 顯示 agent 拗於「先驗證再 commit」或漏開 PR——包成 script 後只能 all-or-nothing,結構性消除漏步。完成這 1 個 Bash 才能 Read spec / 寫 code。 -實作期間每 ~5 個元件 / 頁面 → `bash .claude/scripts/commit-progress.sh "feat: " "$ISSUE_NUM"`。npm install 與 build verify 留到收尾前或交給 CI。 - -## Step 3 `[frontend]`(強制 hard gate):讀本地 design 快照 +### Step 3 🛑 `[frontend]` pixel-perfect gate > 寫任何 frontend 程式碼前**必須**讀過 `specs/design-source/` 本地快照。憑空寫 UI 是 #1 翻車原因。 @@ -63,7 +73,7 @@ ls specs/design-source/screenshots/ # Read tool 可直接讀 PNG 對照視覺 cat specs/contracts/dom.md specs/contracts/ux-text.md specs/contracts.ts ``` -**不 WebFetch 線上 URL** — 本地快照是 sprint 的 SoT。發現本地過舊 → 找 spec-writer 重跑 sync-design.sh,**不自己決定要不要重抓**。 +**不 WebFetch 線上 URL** — 本地快照是 sprint 的 SoT。發現過舊 → 找 spec-writer 重跑 sync-design.sh,不自己決定要不要重抓。 **完全照 design,零自由發揮**: 1. Pixel-perfect 還原(佈局/間距/顏色/字型/圓角/陰影/icon 位置),不因「比較好看」自行調 @@ -71,88 +81,40 @@ cat specs/contracts/dom.md specs/contracts/ux-text.md specs/contracts.ts 3. 文字 100% 一致,逐字對照 `specs/contracts/ux-text.md`,禁改字/翻譯/改標點 4. 互動行為照 design(hover/focus/disabled/loading/error);**design 沒畫的狀態不自行設計** 5. 不「修正」design 問題(覺得有 bug → PR 標 `⚠️ design-question` + 開 issue,不在程式碼偷改) -6. **不增不減**:design 沒有的不加,design 有的不刪 +6. **不增不減**:design 沒有的不加,有的不刪 7. PR 必附 design 對照(實作了哪幾頁/section + 不一致處及原因) design 沒畫的元件/互動/文字 → **不腦補**,開 `design-question` issue 阻塞本 issue(kit §5),由 spec-writer 補回去問使用者。 -## Step 1 🛑 deliver-first(所有 lane,v3 後用 helper script 收成 1 個 Bash) - -撞 harness sub-agent cap 時 **deliverable 必須已在 GitHub**。認領 issue 後**第一個 Bash 必須是這一行**,中間不可插任何別的 tool call: - -```bash -cd /path/to/repo -DRAFT_PR=$(bash .claude/scripts/deliver-first.sh "$ISSUE_NUM" "$SLUG" "$TITLE" "feature,$LANE") -echo "✅ draft PR #${DRAFT_PR} created" -``` - -helper 內部會做:fetch + rebase main → 開 branch → empty commit → push + `gh pr create --draft`,**4 步合 1 個 Bash**。完成這 1 個 Bash 才能開始 Read spec / 寫 code / 跑 npm install。 - -為什麼用 helper:v2/v3 顯示 agent 拗於「先驗證再 commit」或漏第 4 步開 PR。把 4 步包成 1 個 script,agent 只能 all-or-nothing 執行,徹底結構性消除漏步問題。 +## 🚫 收尾禁止「先搞懂再動作」本能(v7 教訓) -實作期間每 ~10 個檔案 → 用另一個 helper 1 個 Bash 完成 commit + push: -```bash -bash .claude/scripts/commit-progress.sh "feat: " "$ISSUE_NUM" -``` - -完工:1 個 Bash 收尾 `bash .claude/scripts/ready-and-merge.sh "$DRAFT_PR"`(draft→ready→等 CI→squash merge 三合一;CI 紅會 exit 1 讓你去修)。 - -**🚫 收尾禁止「先搞懂再動作」本能(v7 教訓)**: -- **不要**手動跑 `gh pr checks` 調查 CI 設定、不要去看 `.github/workflows/`、不要研究「為什麼只有 security check 沒 build-lint」。**沒設 build-lint CI 就是過** — `ready-and-merge.sh` 已處理 no-CI 情況。 -- **不要**為了「確認能 build」而在收尾前補跑 `npm install` / `tsc` / `vite build`。本地 `local-checks.sh`(Step 6)過了就夠;完整 build verify 交給 CI(有的話)或 sprint e2e。 -- v7 backend agent 因為去查 CI workflow、frontend agent 因為想 npm install 驗 build,都在 merge 前撞 cap。**信任 helper,直接跑,省下的 turn 拿去做下一個 issue。** +- **不要**手動跑 `gh pr checks` 調查 CI、不看 `.github/workflows/`、不研究「為什麼沒 build-lint」。**沒設 build-lint CI 就是過**——`ready-and-merge.sh` 已處理 no-CI 情況。 +- **不要**為「確認能 build」在收尾前補跑 `npm install` / `tsc` / `vite build`。本地 `local-checks.sh`(Step 6)過了就夠;完整 build verify 交給 CI 或 sprint e2e。 +- 信任 helper,直接跑,省下的 turn 拿去做下一個 issue。 -## 🛠 環境噪音容忍規則(v2 後新加) +## 🛠 環境噪音容忍規則 -Bash 工具呼叫遇到以下訊號**不算失敗,繼續往下做**: +Bash 遇以下訊號**不算失敗,繼續做**: | 訊號 | 處理 | |---|---| -| stderr 含 `setValueForKeyFakeAssocArray:N: command not found:` | macOS/zsh 環境噪音,**忽略** | +| stderr 含 `setValueForKeyFakeAssocArray:N: command not found:` | macOS/zsh 噪音,**忽略** | | stderr 含 `_encode` / `_decode` / `urltools` 雜訊 | 同上,**忽略** | -| Bash exit code 非 0 但 stdout **有預期結果** | 看 stdout 內容判斷實際成敗,不只看 exit code | -| 同一 git 操作前後互相影響(如 `git checkout` 出現 untracked 警告) | 通常 OK,下一個指令會看到正確狀態 | - -「無進展即停」**只在以下情況觸發**: -- 同一條程式碼(同 file + line)試 2 次修改仍 build/test 紅 -- spec 真實缺資訊(contract 沒寫、AC 含糊) -- 依賴的 feature 真實未完成(dependencies.md 標紅,且 GitHub issue open) - -**環境雜訊不算「無進展」**。 +| Bash exit code 非 0 但 stdout **有預期結果** | 看 stdout 判斷實際成敗 | +| git 操作出現 untracked 警告 | 通常 OK,下個指令會看到正確狀態 | -## 🤝 跨 lane race 處理(v2 後新加) +## 🤝 跨 lane race 處理 -你 cd 到的 demo dir 可能有其他 lane agent 的 untracked 檔(你跑 deliver-first 第 1 步 fetch + rebase 後通常可避免)。如果仍看到非自己寫的檔在 `git status`: +worktree 可能有其他 lane 的 untracked 檔(deliver-first 第 1 步 fetch+rebase 後通常可避免)。若仍看到非自己寫的檔: +- **不要動它們**(屬於別人) +- `git add` 只 add 自己這次寫的具體路徑(用 `git add dev/src/...`,不用 `git add -A`) +- conflict 時 `git pull --rebase origin {your-branch}`;無法 resolve 就用對方版本 + commit「chore: rebase」 -- **不要動它們**(它們屬於別人) -- 你 `git add` 時只 add 自己這次寫的具體路徑(不用 `git add -A`,用 `git add dev/src/...`) -- 看到 conflict 時:`git status` 看是哪個檔,跑 `git pull --rebase origin {your-branch}` 嘗試自動 resolve;無法 resolve 就用對方版本 + commit「chore: rebase」 +## 無進展即停(停損靠判斷,不靠 maxTurns) -## 每個 issue 的執行順序(總覽 — 嚴格照此 Step) - -> 這是權威順序。各 Step 細節在下方同名段落。`[frontend]` 標記僅 frontend lane 做。 - -| Step | 動作 | 細節段落 | -|------|------|---------| -| **1** | 認領 issue 後**第一個 Bash 必須是 `deliver-first.sh`**(draft PR 落 GitHub)| 🛑 deliver-first | -| **2** `[frontend]` | **第二個 Bash 必須是 `frontend-scaffold.sh`**(Vite 骨架,不跑 npm install)| [frontend] frontend-scaffold | -| **3** `[frontend]` | 讀 `specs/design-source/` 本地快照(pixel-perfect 前提)| [frontend] 讀 design 快照 | -| **4** | 讀 issue + spec:`gh issue view {n} --json ...`;`cat specs/features/f{N}-*.md overview.md dependencies.md`。bug 額外讀失敗 scenario + 重現步驟 | — | -| **5** | 實作(`dev/` 下):依 API contract / bug 描述,遵循 overview.md 架構 + 既有風格;寫 unit tests;維護 compose;自驗所有 AC。**每 ~10 檔跑 `commit-progress.sh` push 一次** | — | -| **6** | push 前 / merge 前跑 `bash .claude/scripts/local-checks.sh`(unit + contract,任一紅不准 ready)| — | -| **7** | 收尾**只准跑** `bash .claude/scripts/ready-and-merge.sh "$DRAFT_PR"`(ready→等 CI→squash merge 三合一)→ issue 回報 → loop 下一個 issue | 🛑 deliver-first 末段 | - -> Step 5 的 docker-compose.example.yml 維護見 kit §3;issue 回報 / bug 修復 comment 見 kit §4。 -> npm install 與完整 build verify 留到 Step 6/7 或交給 CI,**不要在 Step 1-4 之間跑**(v3/v5 frontend 撞 cap 主因)。 - -## 程式碼規範 - -遵循專案既有 linter/formatter;命名有意義;避免過度工程;關鍵業務邏輯加註解;不引入不必要依賴。 - -## 注意事項 +**只在以下情況觸發**,環境雜訊不算: +- 同一條程式碼(同 file + line)試 2 次修改仍 build/test 紅 +- spec 真實缺資訊(contract 沒寫、AC 含糊) +- 依賴的 feature 真實未完成(dependencies.md 標紅且 GitHub issue open) -- 只在 `dev/` 工作,不碰 `test/`/`specs/`(contract entry 例外) -- worktree 隔離,獨立分支 -- 依賴的 feature 未完成(查 `specs/dependencies.md`)→ issue 留言回報並停止 -- 描述不清 → issue 留言提問,不自行假設 -- **無進展即停**:同一問題(編譯不過 / 測試紅 / 找不到 contract)試 2 次仍未解 → issue 留言說明卡點與已試方法並停止,**不繞圈燒 turn**(maxTurns 不被 harness 強制,停損靠這條判斷,不靠 maxTurns)。**環境雜訊不算「無進展」** — 見上方「環境噪音容忍規則」 +觸發時 → issue 留言說明卡點與已試方法並停止,**不繞圈燒 turn**。 diff --git a/.claude/shared/kits/engineer-kit.md b/.claude/shared/kits/engineer-kit.md index 86eeba9..28201ff 100644 --- a/.claude/shared/kits/engineer-kit.md +++ b/.claude/shared/kits/engineer-kit.md @@ -95,25 +95,13 @@ docker compose down ## 4. PR + auto-merge(deliver-first 絕對序列) -### 4a. 認領 issue 後的前 4 個 Bash 呼叫(不可插別的 tool call) +### 4a. 認領 issue 後第一個 Bash(deliver-first,不可插別的 tool call) ```bash -# (1) fetch + rebase 防 race -cd "$DEMO_DIR" && git fetch -q origin && git checkout main && git pull -q --rebase -# (2) 開分支 -git checkout -b "feature/${ISSUE_NUM}-${SLUG}" -# (3) empty commit 鎖 branch -git commit --allow-empty -q -m "chore: [WIP] start #${ISSUE_NUM}" -# (4) push + draft PR -git push -u -q origin "feature/${ISSUE_NUM}-${SLUG}" -DRAFT_PR=$(gh pr create --draft --title "[WIP] {Issue 標題}" \ - --body "Closes #${ISSUE_NUM} - -[WIP] Implementation in progress." \ - --label "feature,${LANE}" --milestone "${SPRINT}" --json number --jq .number) +DRAFT_PR=$(bash .claude/scripts/deliver-first.sh "$ISSUE_NUM" "$SLUG" "$TITLE" "feature,$LANE") ``` -**完成這 4 步才能開始 Read spec / 寫 code / npm install**。為什麼這麼硬:v2 benchmark frontend agent 試 `npm install` 先沒推 → 沒 PR;qa commit 完忘 push → 沒 PR。絕對序列防止本能性「先驗證再 commit」。 +script 內部把 fetch+rebase → 開 branch → empty commit → push + 開 draft PR **4 步合 1 個 Bash**(含 retry / idempotent)。**完成這 1 個 Bash 才能開始 Read spec / 寫 code / npm install**——絕對序列防止本能性「先驗證再 commit」(v2 frontend 試 npm install 先沒推→沒 PR;qa commit 完忘 push→沒 PR)。**不要手打這 4 步,一律走 script**(手打版會繞過 retry / idempotent 防護)。 ### 4b. 實作期間每 ~10 檔 commit + push(PR 自動跟上) @@ -124,11 +112,10 @@ Refs #${ISSUE_NUM}" git push ``` -### 4c. 收尾改 ready + auto-merge +### 4c. 收尾:先填 PR 真實 title/body,再走 ready-and-merge.sh ```bash -PR_NUM="${DRAFT_PR}" -gh pr edit "$PR_NUM" --title "{Issue 標題}" --body "$(cat <<'BODY' +gh pr edit "$DRAFT_PR" --title "{Issue 標題}" --body "$(cat <<'BODY' ## Summary {實作摘要} ## Changes @@ -144,9 +131,7 @@ gh pr edit "$PR_NUM" --title "{Issue 標題}" --body "$(cat <<'BODY' Closes #{issue_number} BODY )" -gh pr ready "$PR_NUM" -gh pr checks "$PR_NUM" --watch || { echo "🔴 build-and-lint 失敗,修完再來"; exit 1; } -gh pr merge "$PR_NUM" --squash --delete-branch +bash .claude/scripts/ready-and-merge.sh "$DRAFT_PR" # ready→等 CI→squash merge 三合一;CI 紅 exit 1 ``` issue 回報: diff --git a/.claude/shared/kits/ui-designer-kit.md b/.claude/shared/kits/ui-designer-kit.md index 1046ff8..f3c8e32 100644 --- a/.claude/shared/kits/ui-designer-kit.md +++ b/.claude/shared/kits/ui-designer-kit.md @@ -74,24 +74,13 @@ example.tsx:基於 tech-survey 選定的 UI 框架,列出各 variant/size/ic ## 5. PR 流程(deliver-first:先 draft 後 ready) -### 5a. 認領 design issue 後的前 4 個 Bash(不可插別的 tool call) +### 5a. 認領 design issue 後第一個 Bash(deliver-first,不可插別的 tool call) ```bash -# (1) fetch + rebase -cd "$DEMO_DIR" && git fetch -q origin && git checkout main && git pull -q --rebase -# (2) 開分支 -git checkout -b "design/sprint-${N}-components" -# (3) empty commit -git commit --allow-empty -q -m "chore: [WIP] start design #${DESIGN_ISSUE}" -# (4) push + draft PR -git push -u -q origin "design/sprint-${N}-components" -DRAFT=$(gh pr create --draft --title "[WIP] 🎨 Sprint ${N} UI dataset" \ - --body "Closes #${DESIGN_ISSUE} - -[WIP] Tokens + components in progress." --label "design" --json number --jq .number) +DRAFT=$(bash .claude/scripts/deliver-first.sh "$DESIGN_ISSUE" "sprint-${N}-components" "🎨 Sprint ${N} UI dataset" "design" "design/") ``` -**完成這 4 步才能開始 Read design source / 寫 tokens**。 +script 把 fetch+rebase → 開 branch → empty commit → push + draft PR 4 步合 1(含 retry / idempotent)。**完成這 1 個 Bash 才能開始 Read design source / 寫 tokens**。不要手打這 4 步。 ### 5b. 實作每 ~3 個元件 commit + push @@ -124,8 +113,7 @@ Sprint {N} UI component dataset,供前端 engineer 開發。 Refs #{design_issue_number} BODY )" -gh pr ready "$DRAFT" -gh pr checks "$DRAFT" --watch && gh pr merge "$DRAFT" --squash --delete-branch +bash .claude/scripts/ready-and-merge.sh "$DRAFT" # ready→等 CI→squash merge 三合一 gh issue comment {design_issue_number} --body "🎨 Design PR: #${DRAFT}" gh issue comment {sprint_issue_number} --body "🎨 UI Component Dataset PR: #${DRAFT}" diff --git a/.claude/skills/specflow:start/SKILL.md b/.claude/skills/specflow:start/SKILL.md index 9988573..de660de 100644 --- a/.claude/skills/specflow:start/SKILL.md +++ b/.claude/skills/specflow:start/SKILL.md @@ -146,20 +146,9 @@ fi 1. CI build-and-lint 通過 2. push 前 `local-checks.sh` 通過(engineer / qa agent 自己會跑) -就可以直接 merge。Engineer / QA agent 在自己的 loop 裡發完 PR 就**自行 merge**: +就可以直接 merge。Engineer / QA agent 在自己的 loop 裡發完 PR 就走 `ready-and-merge.sh` **自行 merge**(ready→等 CI→squash merge 三合一)。 -```bash -# Engineer / QA agent loop 內的 merge 邏輯 -gh pr checks {pr_number} --watch # 等 CI 跑完 -gh pr merge {pr_number} --squash --delete-branch # build-and-lint 過就 merge -``` - -**為什麼不 per-PR review**: -- per-PR 看不到跨 lane 對齊問題(frontend testid 對 qa testid 各自看都對,合起來不對) -- Engineer 等 review 卡住 lane drain -- 改成 sprint-end 一次完整 review 看到全貌、找問題更準 - -Branch protection 配合改成只要 `build-and-lint` 過、不再要求 approval(見 `init-github.sh`)。 +Branch protection 配合改成只要 `build-and-lint` 過、不再要求 approval(見 `init-github.sh`)。理由見 `docs/DESIGN-RATIONALE.md`。 ### Phase 4.9:Infra 確認(Sprint 測試前,需使用者確認) @@ -258,13 +247,7 @@ fi - `success` → 進入 Phase 5.5 sprint code review → Phase 5.6 verifier - `failure` → workflow 已自動建 bug issue(lane label 從失敗推測)→ engineer lane 重啟修復 → bug close 自動觸發新 workflow run → orchestrator 重新進入 Phase 5 輪詢 -#### 為什麼 e2e 上 CI - -1. **可重現**:標準 ubuntu env,不受個別開發機影響 -2. **可見性**:team / 使用者直接看 actions tab,不用本機重跑 -3. **Artifacts 集中**:playwright trace / 截圖 / report 在 actions run 裡,30 天保留 -4. **Verifier 信任源**:直接讀 workflow conclusion,不用靠 state.json 自我宣告 -5. **解放本機**:orchestrator 不用佔用 docker port,可以同時做別的事 +> e2e 上 CI 的 5 點理由(可重現 / 可見性 / artifacts 集中 / verifier 信任源 / 解放本機)見 `docs/DESIGN-RATIONALE.md`。 ### Phase 5.5:Sprint Code Review(背景自動,一次性全面審查) diff --git a/docs/DESIGN-RATIONALE.md b/docs/DESIGN-RATIONALE.md new file mode 100644 index 0000000..82e04be --- /dev/null +++ b/docs/DESIGN-RATIONALE.md @@ -0,0 +1,22 @@ +# SpecFlow 設計取捨理由(給人看,不入 prompt) + +本檔收錄 orchestrator / agent 流程「為什麼這樣設計」的說明,從各 SKILL/agent prompt 抽出來,避免常駐 prompt 載入純解釋性散文。改流程前先讀這裡理解原意。 + +## 為什麼不做 per-PR review(改成 sprint-end 一次性 review) + +- per-PR 看不到跨 lane 對齊問題(frontend testid 對 qa testid 各自看都對,合起來不對) +- Engineer 等 review 會卡住 lane drain +- 改成 sprint-end 對整個 sprint diff 一次完整 review,看得到全貌、找問題更準 + +配套:branch protection 改成只要 `build-and-lint` 過、不再要求 approval(見 `init-github.sh`)。 +(對應 `specflow:start` Phase 4.5 / 5.5) + +## 為什麼 e2e 上 CI(不在本機跑) + +1. **可重現**:標準 ubuntu env,不受個別開發機影響 +2. **可見性**:team / 使用者直接看 actions tab,不用本機重跑 +3. **Artifacts 集中**:playwright trace / 截圖 / report 在 actions run 裡,保留 30 天 +4. **Verifier 信任源**:直接讀 workflow conclusion,不用靠 state.json 自我宣告 +5. **解放本機**:orchestrator 不用佔用 docker port,可同時做別的事 + +(對應 `specflow:start` Phase 5)