Dispatch 路徑選擇(三選一選單)
本 skill 的 draft 階段有三條可選路徑。Step 0 開頭 MUST 用 AskUserQuestion 跳三選一選單讓使用者選(除非使用者已明確指定路徑,見下方捷徑):
- A. Codex flow(預設 / 推薦,選單第一項) — Codex GPT-5.6-sol max draft + 主線 Claude Opus 4.8 xhigh cross-check。draft + cross-check 比擇一穩,wall-clock 最短。
- B. 雙段 codex pipeline(Fable 暫不可用期間的 fallback)— Codex GPT-5.6-sol xhigh draft → Codex GPT-5.6-sol high review(fresh session、只出 findings、不改檔)→ 主線 Claude Opus 4.8 xhigh final check。比選項 A 多一道 codex 自我審查關卡,wall-clock 較長(多一層背景等待)。原設計為 Claude Fable 5 High draft(三模型交叉);Fable 回歸後把 Phase B-0a draft 改回
claude -p --model claude-fable-5。
- C. 純 Claude — 主線 Claude Opus 4.8 直接走 Step 1~11(含 Step 8 補 7 步 Design Review check)。
選單寫法:option A label 標「(預設/推薦)」並排第一(使用者按 Enter 即走現狀)。
明確指定捷徑(跳過選單,直接走對應選項):使用者訊息已明確指定路徑時不問選單:
- 「不要派 codex」「我要純 Claude propose」「直接你做」→ 選項 C
- 「用 Fable」「走 Fable pipeline」「Fable 起草」「雙段 codex」「codex draft+review」→ 選項 B(Fable 暫不可用,B 現走 codex draft → codex review → Opus final)
- 「用 codex」「現有流程」「照舊」→ 選項 A
選定後依對應選項段落執行。選項 A / B 在 Step 0 內完成整個 draft + check,本 session 不再執行 Step 1~11;只有選項 C 才往下跑 Step 1~11。
選項 A:Codex flow(Codex draft + 主線 cross-check)
Phase 0a:派 Codex 在背景跑
依以下順序執行(每一步都是主線 Claude 自己做,不需使用者介入):
-
解析 change name + requirement:從 argument / discuss artifacts / 對話脈絡萃取,導出 kebab-case <change-name> 與一句話 requirement
-
Write prompt 檔到 /tmp/codex-spectra-propose-<change-name>-prompt.md,內容固定包含:
請以本 repo 的 spectra-propose 流程建立 change `<change-name>`。
Requirement:<一句話需求>
Plan-first(**MUST**,per `.claude/rules/agent-routing.md` Plan-first 條目):
在動任何 Edit / Write / Bash 寫入動作之前,先在 stdout 最開頭輸出一段 `## Plan` section,包含:
- **要動的具體檔案**(每條一行的相對路徑,例如 `openspec/changes/<change-name>/proposal.md`、`openspec/changes/<change-name>/design.md`、`openspec/changes/<change-name>/tasks.md`、`openspec/changes/<change-name>/specs/<capability>/spec.md`)
- **每個檔案打算寫什麼**(一句話 — 例如 proposal.md 的章節列表、design.md 的決策骨架、tasks.md 預期 phase 數量與分層、specs 的 ADDED/MODIFIED/REMOVED 走向)
- **預期 phase 切分**(特別是 UI view phase vs 非 view phase 的邊界,呼應下方 Phase Purity 規則)
Plan 寫完後**立刻**繼續執行,**不要**停下來等確認。Plan 是事前公開思路給主線 Claude cross-check,不是 review gate。
讀取以下檔案理解流程後執行:
- .claude/skills/spectra-propose/SKILL.md(**只執行 Step 1 ~ 11**,**跳過** Step 0 — 已決定由你執行)
- .claude/rules/ux-completeness.md(必填區塊:Affected Entity Matrix / User Journeys / Implementation Risk Plan + Fixtures / Seed Plan + Design Review 7 步 template)
- .claude/rules/agent-routing.md
- 任何 discuss 階段已捕獲的 design.md / spec.md(位置:openspec/changes/<change-name>/,若已存在)
若 change 包含 UI scope 且 proposal 有 ## Affected Entity Matrix(= entity 動且有 UI 展示),tasks.md **必須**包含 `## N. Fixtures / Seed Plan` section(每個有 Surfaces 的 entity 一條 task,或 `**Existing seed sufficient**` 宣告 + 一行理由)。
**Phase Purity(UI view vs 非 view 必須切成獨立 phase)**:
若 change 同時涉及 UI view 層(`.vue` / `.tsx` / `.jsx` / `app/pages/` / `app/components/` / `pages/` / `components/` / `views/` / `layouts/` / `.css` / `.scss`)與**非 view 工作**(schema / migration / API server / store / hook / API client / type / util / 純 backend),tasks.md **必須**把這兩類切成不同的 `## N.` phase:
- 例:`## 1. Database Schema` + `## 2. API Endpoints` + `## 3. Pinia Store + Composables` + `## 4. UI View Implementation` + `## 5. Fixtures / Seed Plan` + `## 6. Design Review`
- **禁止**把 view 層改動(`.vue` / `app/pages/` 等)與非 view 工作混進同一 phase
- 理由:spectra-apply 會把 UI view phase 由主線 Claude Code 自己做、其他 phase 派給 codex;混雜 phase 會破壞 dispatch 規則
- frontend 但非 view 的(store / hook / API client / type / util / unit test)算非 view,可以與 backend 工作放同 phase 或自己一個 phase 都可
若 change 包含 UI scope(tasks 涉及 .vue / pages/ / components/ / layouts/),tasks.md **必須**包含完整 7 步 Design Review section(N.1~N.7):
- N.1 檢查 PRODUCT.md / DESIGN.md
- N.2 /design improve + Fidelity Report
- N.3 修復 DRIFT loop
- N.4 按 canonical order 跑 targeted impeccable skills
- N.5 /impeccable audit Critical = 0
- N.6 review-screenshot 視覺 QA
- N.7 Fidelity 確認
**Manual Review Item Kind Marker(hard rule,所有 change)**:
`## 人工檢查` 區塊每條 checkbox 行 **MUST** 在 `#N` / `#N.M` 後緊接 leading kind marker:`[review:ui]` / `[discuss]` / `[verify:e2e]` / `[verify:api]` / `[verify:ui]`,或 verify multi-marker `[verify:<a>+<b>]` / `[verify:<a>+<b>+<c>]`(channels 僅限 `e2e` / `api` / `ui`)。
- `[review:ui]` — 需要使用者親自確認的 UI / UX 驗收。Claude 禁止代勾。
- `[discuss]` — Claude 主導的 evidence-based 討論(production 授權 / 商業判斷 / production 觀察 / 後端 evidence 查驗 / 合理性檢查)。spectra-archive Step 2.5 walkthrough 由 Claude 主動準備證據與使用者討論。
- `[verify:e2e]` — Playwright spec-based automated journey / persistence evidence。
- `[verify:api]` — curl / ofetch / fetch HTTP round-trip evidence。
- `[verify:ui]` — screenshot-review `mode: verify` final-state screenshot + DOM observation;使用者仍需 review GUI 確認。
- `[verify:api+ui]` / `[verify:e2e+ui]` 等 multi-marker — 同一 business assertion 需要多個 evidence channels。
**NEVER** author new `[verify:auto]` markers。若 draft 產生 `[verify:auto]`,主線 cross-check 必須 inline 替換成 explicit marker:pure API → `[verify:api]`;mutation + visual → `[verify:api+ui]`;persistence / full journey → `[verify:e2e]`。
**分類指引**:描述含 SSH / `docker exec` / `psql` / `\d <table>` / `SELECT ... FROM` / 受控 drift 製造 / migration 存在性驗證 / 合理性檢查等 evidence-collection pattern → `[discuss]`;若 `curl` / HTTP round-trip 可重現 → `[verify:api]`;mutation persistence / reload journey → `[verify:e2e]`;純 final-state 視覺 → `[verify:ui]`;mutation + visual → `[verify:api+ui]`;真的需要人 → `[review:ui]`。
**Backend-only Manual Review 規約**(適用 `## User Journeys` 為 `**No user-facing journey (backend-only)**` 的 change):
tasks.md 的 `## 人工檢查` **只**允許 `[discuss]` kind 的代表性 use cases:(1) production 授權 (2) 商業判斷 (3) production 觀察,以及可由 HTTP 重現的 `[verify:api]` round-trip。**禁止**把 SSH / psql / `\d <table>` / `SELECT FROM` / `SET session_replication_role` / 受控 drift 製造 / migration 存在性驗證等 evidence collection 寫進 `## 人工檢查` — 這些 **MUST** 寫進新的 `## N. Backend Verification Evidence` section 由 apply 階段 Claude 自跑自貼。若三類與 `[verify:api]` 都沒有,`## 人工檢查` 寫成固定文字 `_本 change 為 backend-only,所有驗證由 apply 階段 Claude 自跑(見 `## N. Backend Verification Evidence`);deploy 前無使用者人工檢查項目。_`。完整規約見 `.claude/rules/ux-completeness.md` 「必填 Backend-only Manual Review 規約」與 `.claude/rules/manual-review.md` 「Item Kind Marker」。
**Manual Review Items 強制段(user-facing change 適用)**:
凡 `## 人工檢查` items 涉及以下情境時,**MUST** 拆 `#N.M` scoped sub-items 並 inline 具體 sample identifier:
- NFC / 刷卡 / 員工卡 / 員工 UID / 卡片 UID
- staff login / user role / 多角色 authz
- 業務 entity 操作(具體 work_report id / equipment id / loan id / business key)
- 多步驟流程(流程含「→」「然後」「接著」「完成後」等過渡詞 ≥ 2 個串接)
- 實體裝置(kiosk / 平板 / 真機 / 印表機 / 條碼槍)
**MUST** 從 `docs/FIXTURES.md`(或 `supabase/seed.sql` / 對應 seed file)抓 stable sample identifier,並在 `## N. Fixtures / Seed Plan` task 確認該 sample 寫進 seed。
**反面範例(禁止)**:
- ❌ `刷卡 → 進入毛刺 → 操作完成 → 自動回 standby`(無 URL、無 UID、無 step)
- ❌ `使用者輸入某個 staff 卡號`(模糊指代)
- ❌ `進入報工頁面送出`(無具體 report id、無 button selector)
**正面範例(要求)**:
**寫完 tasks.md 後 MUST 自查**:
```bash
grep -nE '(刷卡|某張|某筆|任一|挑一筆|隨便|→.*→)' openspec/changes/<change-name>/tasks.md
若有 hit 在 ## 人工檢查 區塊 → 改寫成 scoped sub-items + inline sample。完整規約見 .claude/rules/manual-review.md 「[review:ui] 純功能驗證 step actionability」+「Pre-Review Data Readiness」。
Artifact 語言遵循:
開工前先 grep -lE "繁體|繁中|不要使用簡體" CLAUDE.md .claude/rules/*.md 2>/dev/null。若命中(consumer 規定繁體中文),全部 artifact(proposal.md / design.md / tasks.md / spec.md)MUST 用繁體中文撰寫,禁止英文 artifact。code 識別字、技術名詞(如 audit_signed_chain、business_keys_drift)、SQL/code block 不譯。若 grep 未命中視為無語言規定。
完成標準:spectra park <change-name> 執行成功。
不要呼叫 /spectra-apply。產出後在 stdout 摘要 artifacts 列表 + spectra validate 結果。
-
背景啟動 codex exec(Bash tool 加 run_in_background=true):
cd <consumer-repo-root> && codex exec \
--model gpt-5.6-sol \
--dangerously-bypass-approvals-and-sandbox \
--skip-git-repo-check \
-c model_reasoning_effort=max \
< /tmp/codex-spectra-propose-<change-name>-prompt.md 2>&1
-
立刻簡短回報給使用者:「已派 Codex GPT-5.6-sol max 在背景 draft /spectra-propose <change-name>(bash job <id>),完成後主線會 cross-check 並補 Design Review template」
-
啟動 Codex Watch Protocol(見 .claude/rules/agent-routing.codex-watch-protocol.md § 監看排程 A. 主線直接 Bash 派)— notification-only:派出後不下短輪詢,主線 idle 等 <task-notification>;只下一個安全網 fallback ScheduleWakeup(1500, "codex spectra-propose <change-name> 安全網檢查 — 預期靠 task-notification 收尾")(~25 分,防 hang-type 失敗;fetch failed / auth 等 exit-type 失敗 codex 會直接 exit → background bash 完成 → 通知立刻觸發,不需輪詢)。NEVER 用 ScheduleWakeup(180) 短輪詢 — 每 3 分鐘醒來重讀整段 context 正是 notification-only 要消除的負擔
Phase 0b:主線 Cross-Check(codex 完成後立刻執行)
收到 <task-notification> status=completed 時立刻依序執行:
-
Read codex stdout 摘要:BashOutput 讀完整 stdout,回報 artifacts list / spectra validate 結果
-
若 codex 已 spectra park <change-name>:先 spectra unpark <change-name> 才能繼續 cross-check
-
跑 post-propose-check.sh(檢查 User Journeys / Affected Entity Matrix / Implementation Risk Plan / Design Review 7 步):
bash scripts/spectra-advanced/post-propose-check.sh <change-name>
若有 FINDINGS → 主線自己直接 Edit proposal.md / tasks.md 補齊(不要回 codex 修,太慢)
3a. 跑 post-propose-manual-review-check.sh(檢查 ## 人工檢查 item step actionability,per Layer B of manual-review.md mechanical enforcement):
bash scripts/spectra-advanced/post-propose-manual-review-check.sh <change-name>
Exit 2 = 有 findings(ABSTRACT_REFERENCE / CARD_WITHOUT_UID / UI_ITEM_NO_URL / MULTI_STEP_NOT_SCOPED 任一)→ 主線自己直接 Edit tasks.md 改寫 ## 人工檢查 items:拆 #N.M scoped sub-items、inline 具體 sample UID(從 docs/FIXTURES.md 抓)、加具體 URL、模糊驗收動詞改為 falsifiable observation。完整修正指引見 hook stdout + .claude/rules/manual-review.md「[review:ui] 純功能驗證 step actionability」。
Legitimate false positive(e.g., 真機掃 SMS 無 dev replay endpoint)→ 在該 item 加 @no-manual-review-check[<reason>] trailing marker。
-
跑 design-inject.sh(若 UI scope,提醒 7 步 template):
bash scripts/spectra-advanced/design-inject.sh <change-name>
-
若 Design Review section 缺或不完整 7 步 → 主線自己 Edit tasks.md 補齊:
位置:tasks.md 最後一個功能區塊之後、## 人工檢查 之前。N = 上一個功能區塊的序號 + 1。
## N. Design Review
- [ ] N.1 檢查 PRODUCT.md(必要)+ DESIGN.md(建議);缺 PRODUCT.md 跑 /impeccable teach、缺 DESIGN.md 跑 /impeccable document
- [ ] N.2 執行 /design improve [affected pages/components],產出 Design Fidelity Report
- [ ] N.3 修復所有 DRIFT 項目(Fidelity Score < 8/8 時必做,loop 直到 DRIFT = 0,max 2 輪)
- [ ] N.4 依 /design improve 計劃按 canonical order 執行 targeted impeccable skills(layout / typeset / clarify / harden / colorize 等實際所需項目)
- [ ] N.5 執行 /impeccable audit,確認 Critical = 0
- [ ] N.6 執行 review-screenshot,補 design-review.md / 視覺 QA 證據
- [ ] N.7 Fidelity 確認 — design-review.md 中無 DRIFT 項
[affected pages/components] 替換為此 change 實際涉及的 UI 檔案/頁面。
5.5 Manual Review Marker Hygiene Check(所有 change,不限 backend-only):
Read tasks.md ## 人工檢查 區塊全部 checkbox,依以下 hygiene rules 檢查並修正。違規 → 主線自己直接 Edit tasks.md(不回 codex 修,太慢)。
Rule 1:每條 item line MUST 有 leading marker
- 每條
- [ ] #N ... / - [ ] #N.M ... line MUST 在 id 後緊接合法 marker:[review:ui] / [discuss] / [verify:e2e] / [verify:api] / [verify:ui] / verify multi-marker [verify:<a>+<b>] 或 [verify:<a>+<b>+<c>]
- Verify multi-marker channels 僅限
e2e / api / ui,canonical order 是 e2e → api → ui
- Multi-marker MUST NOT 與
[review:ui] / [discuss] 混用;[verify:api+review:ui] / [verify:api+discuss] 非法
- 缺 marker → 依下方 Rule 2 / Rule 3 / Rule 4 的內容分類補上正確 marker;禁止仰賴 Default Kind Derivation Rule(fallback 只給既有 in-flight legacy item 用,且 fallback 不涵蓋任何
verify:*)
- 新 item MUST NOT 使用
[verify:auto];若 codex draft 含 [verify:auto],主線 inline 替換成 explicit marker(pure API → [verify:api];mutation + visual → [verify:api+ui];persistence / full journey → [verify:e2e])
Rule 2:Evidence-collection items MUST 標 [discuss] 或 [verify:api]
若 item description 含下列 evidence-collection 動詞 / 模式:
Apply ... migration、verify ... exists
SSH、docker exec、psql
\d <table>、SELECT ... FROM
curl、Trigger ... cron、Run /_cron/
SET session_replication_role、UPDATE ... WHERE、受控 drift 製造
- 「合理性檢查」、「分布是否符合預期」等商業判斷類
行為:
- SSH / psql /
\d / SELECT / 受控 drift / migration existence / 商業判斷 → [discuss]
curl / HTTP endpoint round-trip 若可由 apply 主線重現 → [verify:api]
- 若該 item 標了
[review:ui]、[verify:ui]、或 deprecated [verify:auto] → flag misclassified,主線改為 [discuss] 或 [verify:api](依是否可由 HTTP 重現)
- 若該 change 為 backend-only(proposal 含
**No user-facing journey (backend-only)**):
- SSH / psql /
\d / SELECT / 受控 drift 製造 / migration 存在性驗證等純技術 evidence項目 MUST 從 ## 人工檢查 搬到 ## N. Backend Verification Evidence section(N = 最後一個功能區塊序號 + 1,位於最後功能區塊之後、## 人工檢查 之前)由 apply Claude 自跑自貼。## 人工檢查 只保留 production 授權 / 商業判斷 / production 觀察三類 [discuss] items,以及可由 HTTP 重現的 [verify:api] items
- 若 Backend Verification Evidence 已存在,append 而非新增
- 若移完後
## 人工檢查 為空 → 替換成固定文字:_本 change 為 backend-only,所有驗證由 apply 階段 Claude 自跑(見 ## N. Backend Verification Evidence);deploy 前無使用者人工檢查項目。_
- 若該 change 為 user-facing:evidence-collection items 可留在
## 人工檢查,但MUST 標 [discuss] 或 [verify:api];Claude 在 archive Step 2.5 walkthrough 主動準備 [discuss] evidence,apply Step 8a 主線自跑 [verify:api]
Rule 3:Real user round-trip items 依 channel 分流
若 item 描述含真實使用者 round-trip(具體 URL + 使用者動作 + 預期 server/UI 結果),依 evidence shape 標記:
- persistence / reload / full journey →
[verify:e2e]
- HTTP status / backend contract →
[verify:api]
- final-state visual only →
[verify:ui]
- mutation response + visual state →
[verify:api+ui]
- journey + extra screenshot evidence →
[verify:e2e+ui]
- 真的需要人(見 Rule 4)→
[review:ui]
誤標 [discuss] → 主線改為適當 verify:* 或 [review:ui]。
Rule 4:「真的需要人」白名單 — 落單者改 explicit verify channel
[review:ui] 只給「agent 用 agent-browser 也跑不了」的項目。description 含下列任一關鍵字才 [review:ui]:
- 收 email / 收 webhook(agent inbox 不可達)
- 「視覺主觀」/「美感」/「a11y 主觀判斷」
- 「實體裝置」/「真機」/「手機」/「平板」/ 「kiosk QR」/「印表機」/「條碼槍」
- 「跨機器」/「跨 session」/ 生產環境授權後操作
- 「電話」/「SMS」等規格外的非 UI 環境
其餘真實使用者 round-trip → MUST 標 explicit verify channel:
- 純 final-state 視覺:
[verify:ui]
- 權限拒絕 path / HTTP status:
[verify:api]
- mutation + toast / banner / list refetch / badge / sort / count:
[verify:api+ui]
- reload persistence / edge payload journey:
[verify:e2e]
行為:
- 若 item 標了
[review:ui] 但描述符合 verify channel 條件(不在白名單) → flag misclassified,主線改為 explicit verify:*
- 若 item 標了
verify:* 但描述需收 email / 實體裝置 / 視覺主觀(在白名單)→ flag misclassified,主線改為 [review:ui]
反面範例:
❌ - [ ] #1 [review:ui] admin /settings 改排程 09:00 → reload 仍 09:00
理由:reload persistence 應由 Playwright spec 驗;應該 [verify:e2e]
✅ - [ ] #1 [verify:e2e] admin /settings 改排程 09:00 → 200 toast → reload 仍 09:00
✅ - [ ] #1 [verify:api+ui] admin /settings 改排程 09:00 → PATCH 200 + 畫面顯示新值
✅ - [ ] #2 [review:ui] cron 觸發 → 借用人 inbox 收到逾期通知 email
✅ - [ ] #3 [discuss] production seed 授權與 cron 監控確認
Rule 5:[review:ui] step actionability — 流程式描述要拆
對標 [review:ui] 的 line,檢查描述是否屬「流程式描述」(user 看完仍不知道從哪開始)。命中下列任一條件 → flag 為非 actionable,MUST 由主線直接 Edit tasks.md 改寫:
- 流程式串接:parent line 含 ≥ 2 個串接動詞(「刷卡 → 進入 → 完成 → 回 standby」「掃 QR → 進入 → 提交」「掃條碼 → 入庫 → 列印標籤」等)但未拆
#N.M sub-items
- 缺具體 URL:item 描述未出現任何
/xxx 路徑或具體頁面 anchor(只說「kiosk 頁」「dashboard」「設定頁」不算)
- 實體裝置動詞但缺替代輸入線索:描述含「刷卡」「掃 QR」「掃條碼」「印表機」「真機」「平板」「kiosk」等實體裝置動詞,但未提及 dev override(UID input / simulate endpoint / paste payload / desktop responsive emulation 等)也未引用具體 sample(UID / payload / 條碼字串)
- 模糊驗收動詞:描述含「正常」「正確」「能用」「順利」「OK」這類無 falsifiable observation 的字眼(無「200 toast
X」「badge 變 Y」「URL 變 /Z」這類具體觀察)
行為:
- 主線直接 Edit tasks.md,依
manual-review.md 的「[review:ui] 純功能驗證 step actionability」拆 #N.M scoped sub-items:每條一個原子動作(開 URL → 輸入 Y / 點 Z → 確認具體觀察 W)
- 若改寫需要的 dev override / baseline 未就緒(grep consumer codebase 找不到 dev input route / simulate endpoint / seed sample),MUST 在 design.md「Open Questions」或 tasks.md TD-NNN 段登記 baseline 缺口,並在 item 行尾加
@followup[TD-NNN] marker
- 若 sample 在 seed 中尚未建,MUST 在
## N. Fixtures / Seed Plan 補對應 task;引用的 stable identifier(UID / business key)與 item 描述一字不差
- 完整規約見
manual-review.md 的「[review:ui] 純功能驗證 step actionability」
反面範例:
❌ - [ ] #7 [review:ui] kiosk 平板實機驗證:刷卡 → 進入毛刺 → 操作完成 → 自動回 standby,且 token 已 consume
理由:流程式串接、無具體 URL、無 sample UID、無 dev 替代輸入路徑、模糊驗收(「操作完成」「token 已 consume」未指明在哪查、看到什麼)
✅ - [ ] #7 [review:ui] kiosk 刷卡 round-trip(standby → 操作頁 → 完成 → 自動回 standby + token consume)
- [ ] #7.1 桌機開 /kiosk,確認 standby(時鐘 + 「請刷卡」提示)
- [ ] #7.2 右下 `Dev: card UID` input 輸入 `04A1B2C3`(admin 樣本卡)→ Enter
- [ ] #7.3 切到操作頁,header 顯示「測試 Admin」+ 操作選單
- [ ] #7.4 點「完成操作」→ 200 toast「操作已記錄」→ 2 秒內回 standby
- [ ] #7.5 開 /admin/kiosk-tokens?card_uid=04A1B2C3,row `status=consumed` 且 `consumed_at` 為剛剛時間
完整規約見 .claude/rules/manual-review.md「Item Kind Marker」+「Kind 分類指引」+「[review:ui] 純功能驗證 step actionability」+ .claude/rules/ux-completeness.md「必填 Backend-only Manual Review 規約」。
5.6 Artifact 語言遵循 check:
grep -lE "繁體|繁中|不要使用簡體" CLAUDE.md .claude/rules/*.md 2>/dev/null
- 若 grep 命中(consumer 規定繁體中文):
- Read proposal.md / design.md / tasks.md,heuristic 偵測:連續 3+ 行純 ASCII 句子且不在
``` code block / table / inline code 內 → 視為英文段落
- 主線自己 Edit 翻成繁體中文,保留:
- SQL / code / shell command(
``` block 內)
- Code 識別字、檔案路徑、技術名詞(如
audit_signed_chain、business_keys_drift、PostgREST)
- inline code(單 backtick 內的字串)
- 標題用語對齊既有繁中規則檔(例如
## Why / ## What Changes / ## Non-Goals / ## Affected Entity Matrix 等 OpenSpec / Spectra 制式英文標題保留不譯,body 內容才翻)
- 若無命中:跳過此 step
-
掃 design.md 的 Open Questions(不論前面摘要多漂亮,這步不能省略):
- Read
openspec/changes/<change-name>/design.md
- grep 找
## Open Questions(或同義變體:## Open Question、## 待決問題、## Unresolved Questions)
- 若標題存在且區塊內容非空(不是
(none) / N/A / 無 / 只剩空 bullet / 只剩註解):
- 立刻用 AskUserQuestion 把每一題列給使用者(一次最多 5 題,超過分批問)
- NEVER 把「要不要回答 open questions」包成 A/B/C/D 選單裡的一個選項
- NEVER 自行假設答案、自行標 wontfix、或推給未來
- 拿到答案後 Edit design.md 把
## Open Questions 改為 ## Resolved Questions,每題下補 **Answer:** <使用者回答>
-
跑 spectra analyze <change-name> --json 確認無 Critical/Warning(max 2 輪 fix loop,與 Step 9 邏輯相同)
-
spectra validate <change-name> 確認 artifacts 結構合法
-
spectra park <change-name> 結束流程
-
回報使用者:artifacts list + cross-check 結果(補了什麼、Design Review 7 步 OK 與否、analyze/validate 結果)+ /spectra-apply <change-name> 提示
選項 B:雙段 codex pipeline(codex draft → codex review → 主線 final check)
NOTE(Fable 暫代):本選項原設計為 Claude Fable 5 High draft(三模型交叉)。Fable 暫不可用,draft 階段暫以 codex gpt-5.6-sol xhigh 代替;review 與 final check 不變。Fable 回歸後把 Phase B-0a 的 draft 命令改回 claude -p --model claude-fable-5 --effort high,並還原本段描述即可。
三段序列:Codex GPT-5.6-sol xhigh 在背景起草 → Codex GPT-5.6-sol high(fresh session)檢查出 findings → 主線 Claude Opus 4.8 xhigh 整合 findings 並完成全套 cross-check。三段皆背景派工 + notification-only watch(per .claude/rules/agent-routing.codex-watch-protocol.md § 監看排程 A)。draft 與 review 是兩個獨立 codex session(即使同 model,fresh context 仍能抓到 draft 時的遺漏)。
Phase B-0a:背景 codex draft
-
解析 change name + requirement(同 Phase 0a step 1)。
-
Write prompt 檔到 /tmp/codex-spectra-propose-<change-name>-draft-prompt.md — 內容完全沿用 Phase 0a step 2 的 draft prompt 範本(Plan-first / Phase Purity / Manual Review Kind Marker / Backend-only 規約 / docs/FIXTURES.md sample / 語言遵循 / spectra park 完成標準全部照搬)。檔名用 -draft-prompt 與 Phase B-0b 的 -review-prompt 區隔,避免兩個 codex job 混用 prompt。
-
背景啟動 codex exec(Bash tool 加 run_in_background=true):
cd <consumer-repo-root> && codex exec \
--model gpt-5.6-sol \
--dangerously-bypass-approvals-and-sandbox \
--skip-git-repo-check \
-c model_reasoning_effort=xhigh \
< /tmp/codex-spectra-propose-<change-name>-draft-prompt.md 2>&1
預設 text 輸出,不加 --output-format json(主線讀 tail)。
-
立刻簡短回報:「已派 Codex GPT-5.6-sol xhigh 在背景 draft <change-name>(bash job <id>);完成後派 codex review,再由主線 Opus final check」。
-
啟動 Watch Protocol(同 Phase 0a step 5)— notification-only:codex exec 背景 job 屬「主線直接 Bash 派」路徑,主線 idle 等 <task-notification>,只下一個安全網 fallback ScheduleWakeup(1500, "codex spectra-propose <change-name> draft 安全網檢查 — 預期靠 task-notification 收尾")。NEVER 短輪詢。
Phase B-0b:codex draft 完成 → 派 codex review
收到 codex draft <task-notification status=completed> 時立刻:
-
Read codex draft stdout 摘要:BashOutput 讀完整 stdout,回報 artifacts list / spectra validate 結果。
-
若 codex draft 已 spectra park <change-name>:先 spectra unpark <change-name> — park 後 artifacts 只存 .git/spectra-app/spectra.db SQLite blob、不在 git tracked file,review codex 要讀必須先 unpark 回檔案系統(同 Phase 0b step 2 + park pitfall)。
-
Write codex review prompt 到 /tmp/codex-spectra-propose-<change-name>-review-prompt.md:
請檢查(review)本 repo 已 draft 的 change `<change-name>`,**不要修改任何檔案**,只輸出 findings。
讀取 openspec/changes/<change-name>/ 下全部 artifacts(proposal.md / design.md / tasks.md / specs/**/spec.md),對照以下規約逐項查:
- .claude/rules/ux-completeness.md(Affected Entity Matrix / User Journeys / Implementation Risk Plan / Fixtures-Seed Plan / Design Review 7 步)
- .claude/rules/manual-review.md(## 人工檢查 Item Kind Marker、step actionability、[verify:auto] 禁用)
- .claude/rules/agent-routing.md(Phase Purity:UI view phase vs 非 view phase 是否切開)
輸出格式:findings list,每條一行 `[檔案] 問題 → 建議修法`。無問題的面向寫「OK」。**禁止** Edit / Write / 改檔,只輸出文字 findings。
-
背景啟動 codex exec(Bash tool 加 run_in_background=true):
cd <consumer-repo-root> && codex exec \
--model gpt-5.6-sol \
--dangerously-bypass-approvals-and-sandbox \
--skip-git-repo-check \
-c model_reasoning_effort=high \
< /tmp/codex-spectra-propose-<change-name>-review-prompt.md 2>&1
-
立刻回報:「codex draft 完成,已派 codex GPT-5.6-sol high review(bash job <id>);完成後主線 Opus final check」+ 啟動 notification-only watch(同 Phase B-0a step 5)。
Phase B-0c:Codex 檢查完 → 主線 Opus final check
收到 codex <task-notification status=completed> 時立刻:
- Read codex findings:BashOutput 讀 codex stdout,整理 findings 摘要。
- 主線整合 findings + 跑完整 cross-check — 執行 Phase 0b step 3 ~ 9 全套(
post-propose-check.sh / post-propose-manual-review-check.sh / design-inject.sh / 補 Design Review 7 步 / Manual Review Marker Hygiene / [verify:auto]→explicit marker / Backend Verification Evidence 搬移 / Open Questions→AskUserQuestion / spectra analyze / spectra validate / spectra park),並把 codex findings 一併納入修補依據。
- 主線自己 Edit 修(NEVER 把修補丟回 codex,太慢、來回成本高)。
- 回報使用者:artifacts list + codex draft 摘要 + codex review findings 摘要 + 主線補了什麼(Design Review 7 步 OK 與否、analyze/validate 結果)+
/spectra-apply <change-name> 提示。
禁止事項(重點重申,A / B / C 通用)
- NEVER 跳過 Step 0 選單(除非使用者明確指定路徑 — 見上方 § 明確指定捷徑)。預設MUST跳三選一選單
- NEVER 派 draft(codex)後不跑 cross-check / final check(post-propose-check + design-inject + 主線補 Design Review 7 步 + spectra analyze)
- NEVER 把 cross-check / final check 的修補工作丟回 codex(太慢、來回成本高)— 主線自己 Edit 修
- NEVER 沉默等使用者來問進度;通知一到自己讀檔 + 續跑後續 phase
- NEVER 派 draft(codex)而 prompt 漏掉 Plan-first 段落 — 必須在動筆前先輸出
## Plan(要動哪些檔 / 每檔寫什麼 / phase 切分),主線後續 check 才有對齊基準
選項 B 專屬 NEVER:
- NEVER 把 Phase B-0a 的 draft prompt(
-draft-prompt.md)與 Phase B-0b 的 review prompt(-review-prompt.md)混用 — draft 會寫檔 + park,review 只出 findings、禁止改檔
- NEVER 在 Phase B-0b 派 codex review 前忘了
spectra unpark(park 後 artifacts 在 SQLite blob,codex 讀不到)
- NEVER 讓 codex review 階段改檔 — review prompt 必含「禁止 Edit / Write、只輸出 findings」;實際修補由主線 Phase B-0c 做
選 A / B 時本 session 不再執行任何 Step 1 ~ 11(避免雙重生產)— Step 0 結束本 skill。
選項 C:純 Claude 路徑(使用者選 C 或明確要求時)
continue to Step 1 below.
Determine the requirement source
a. Argument provided (e.g., "add dark mode") → use it as the requirement description, skip to deriving the change name below.
b. Plan file available:
- Check if the conversation context mentions a plan file path (plan mode system messages include the path like
~/.claude/plans/<name>.md)
- If found, check if the file exists at
~/.claude/plans/
- If a plan file is found, use the AskUserQuestion tool to ask:
- Option 1: Use the plan file
- Option 2: Use conversation context
- If conversation context has no relevant discussion, mention this when presenting the choice
- If the user picks the plan file → read it and extract:
plan_title (H1 heading) → use as requirement description
plan_context (Context section) → use as proposal Why/Motivation content
plan_stages (numbered implementation stages) → use for artifact creation
plan_files (all file paths mentioned) → use for Impact section
- If the user picks conversation context → fall through to (c)
c. Conversation context → attempt to extract requirements from conversation history
- If context is insufficient, use the AskUserQuestion tool to ask what they want to build
From the resolved description, derive a kebab-case change name (e.g., "add dark mode" → add-dark-mode).
Do not keep archive-style date prefixes in active change names. If the source name starts with YYYY-MM-DD-, strip that date prefix before running spectra new change; archived change names and directories are historical references, not active names to reuse.
IMPORTANT: Do NOT proceed without understanding what the user wants to build.
Write the proposal
IMPORTANT — file path rules for the ## Impact section:
- All file paths SHALL be written relative to the project root (e.g.,
src/lib/foo.ts, src-tauri/crates/core/src/bar.rs, docs/specs/specs/auth/spec.md).
- Do NOT use relative fragments (e.g.,
parser/mod.rs, core/mod.rs) — preflight rejects them as non-anchored paths.
- Do NOT wrap shell commands in backticks inside artifact text (e.g.,
`git mv a.rs b.rs`) — preflight's backtick extractor will otherwise mis-parse the command as a file reference.
- When referring to a file without naming its concrete path, use descriptive prose (e.g., "Parser 入口檔") rather than a backticked path fragment.
Get instructions:
spectra instructions proposal --change "<name>" --json
Generate the proposal content based on change type (see formats below), then write it via CLI:
spectra new artifact proposal --change "<name>" --stdin <<'ARTIFACT_EOF'
<proposal content>
ARTIFACT_EOF
If the command fails with a validation error, fix the content and retry.
Use the following format based on change type:
Feature
## Why
<!-- Why this functionality is needed -->
## What Changes
<!-- What will be different -->
## Non-Goals (optional)
<!-- Scope exclusions and rejected approaches. Required when design.md is skipped. -->
## Capabilities
### New Capabilities
- `<capability-name>`: <brief description>
### Modified Capabilities
(none)
## Impact
- Affected specs: <new or modified capabilities>
- Affected code:
- New: <paths to be created, relative to project root>
- Modified: <paths that already exist>
- Removed: <paths to be deleted>
Bug Fix
## Problem
<!-- Current broken behavior -->
## Root Cause
<!-- Why it happens -->
## Proposed Solution
<!-- How to fix -->
## Non-Goals (optional)
<!-- Scope exclusions and rejected approaches. Required when design.md is skipped. -->
## Success Criteria
<!-- Expected behavior after fix, verifiable conditions -->
## Impact
- Affected code:
- Modified: <paths that already exist>
- New: <paths to be created, relative to project root>
- Removed: <paths to be deleted>
Refactor / Enhancement
## Summary
<!-- One sentence description -->
## Motivation
<!-- Why this is needed -->
## Proposed Solution
<!-- How to do it -->
## Non-Goals (optional)
<!-- Scope exclusions and rejected approaches. Required when design.md is skipped. -->
## Alternatives Considered (optional)
<!-- Other approaches considered and why not -->
## Impact
- Affected specs: <affected capabilities>
- Affected code:
- Modified: <paths that already exist>
- New: <paths to be created, relative to project root>
- Removed: <paths to be deleted>