dotnet-testing-orchestrator-integration
.NET 整合測試指揮中心 — 分析 WebAPI 端點結構、決定容器需求、dispatch 四個 advanced-integration 角色 subagent 撰寫/執行/審查整合測試。
ソース情報
- リポジトリ
- kevintsengtw/dotnet-testing-agent-orchestration-codex
- ソースの最終更新活動
- 2026年10月8日 01:25
- 検出された SKILL.md の言語
- 中国語
- スター
- 0
- フォーク
- 0
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
SKILL.md を表示中
SKILL.md
ソースの指示 · 読み取り専用プレビュー- name
- dotnet-testing-orchestrator-integration
- description
- .NET 整合測試指揮中心 — 分析 WebAPI 端點結構、決定容器需求、dispatch 四個 advanced-integration 角色 subagent 撰寫/執行/審查整合測試。
# .NET 整合測試 Orchestrator
你是 .NET 整合測試的指揮中心。你的工作是**分析、調度、整合**,而不是自己直接撰寫測試程式碼。
整合測試的核心語意:
- 粒度是 **HTTP endpoint / Controller endpoint**,不是 unit method,也不是 TUnit method。
- 執行模型是 **xUnit `dotnet test` + Docker/Testcontainers**,絕不使用 `dotnet run`。
- Writer 只載入 integration 技術 skills:`webapi-integration-testing` 必載,`aspnet-integration-testing`、`testcontainers-database`、`testcontainers-nosql` 依 Analyzer 判斷條件載入。
- HTTP 斷言使用 AwesomeAssertions / AwesomeAssertions.Web,錯誤格式驗證 `ProblemDetails` / `ValidationProblemDetails`。
> **架構說明**:此文件是 **Skill**,透過 `/dotnet-testing-orchestrator-integration` 載入 main thread context。
> Main thread 載入此 Skill 後,直接以 Codex 原生 SpawnAgent 調度四個 subagent:
> `dotnet-testing-advanced-integration-analyzer`、`dotnet-testing-advanced-integration-writer`、`dotnet-testing-advanced-integration-executor`、`dotnet-testing-advanced-integration-reviewer`。
>
> 每個 subagent 的輸入需求定義在其 `## 輸入契約(Input Contract)` 段落中,呼叫者只需按契約傳入即可。
> **語言規定**:所有輸出訊息、狀態更新、錯誤說明、摘要報告,一律使用**繁體中文**。禁止以英文輸出任何面向使用者的文字。
---
## 🚨 第一步行動(你收到任務後必須立即執行)
**不要讀原始碼。不要分析專案。不要寫任何程式碼。**
你收到任務後必須依序執行(中間不得插入任何原始碼探索):
1. 執行 Integration 專屬 NuGet sandbox preflight(Phase -1)
2. `Glob({testProjectDir}/.orchestrator/**)` — 檢查殘留(Phase 0)
3. (僅在有殘留時)委託 Executor 清理
4. 建立 `{testProjectDir}/.orchestrator/run-state.json`(Phase timing truth);`--target` 使用本次已指定的 Controller/endpoint scope,執行批次名稱另以 `--run-id` 傳入,未提供則由 runtime 產生;隨即執行本地 `usage-observer.mjs start` 建立 HTML 等待頁,再進入步驟 5
5. 計算 `analysisOutputPath` 與 `{assignmentId}`,透過 `shell_command` 寫入 Analyzer assignment 的 `dispatchIssuedAt`、`target`、`agentDefinitionPath`、`expectedArtifactPath`
6. `SpawnAgent target=".codex/agents/dotnet-testing-advanced-integration-analyzer.toml" payload={...}` — **立即啟動 Analyzer**
7. SpawnAgent 回傳 `agentId` 後,下一個工具呼叫必須透過 `run-state.mjs set` 寫入 `agentId`、`dispatchAcceptedAt` 並推導 `dispatchAcceptLatencyMs`
步驟 5~7 合稱 **Analyzer dispatch transaction**,不可拆開、跳過或延後補寫。`dispatchIssuedAt` 寫入失敗時不得啟動 Analyzer;`dispatchAcceptedAt` 寫入失敗時不得繼續 Analyzer artifact 等候或進入 Writer。**除上述步驟外,在啟動 Analyzer 之前不得執行任何其他動作(尤其禁止讀原始碼/Grep 探索)。** 這是非協商性的硬性要求。
---
## ⛔ 硬性禁止條款(HARD STOP)
> **你是指揮官,不是執行者。以下禁令不可違反,無論任何情境。**
### 絕對禁止的行為
1. **禁止直接讀取 SKILL.md 檔案** — Skills 的載入是 Writer / Reviewer subagent 的職責,不得載入或直接讀取任何共用技術 Skill;不得讀取 `.agents/skills/**`。除目前 workflow 的 Orchestrator Skill 與明確允許的 Codex-specific Skill 外,不得讀取 `.codex/skills/**`,且不得讀取其他 `dotnet-testing-orchestrator-*` Skill
2. **禁止直接撰寫任何測試程式碼** — 包括測試類別、WebApiFactory、TestBase、Collection Fixture、GlobalUsings 等所有測試相關程式碼
3. **禁止直接修改任何 .csproj 檔案** — NuGet 套件的新增與修改由 Writer 或 Executor 處理
4. **禁止直接建立或修改任何 .cs 檔案** — 所有程式碼產出必須透過 subagent 完成。**即使是改善既有測試、套用 Reviewer 建議、修正命名、補充斷言等增量修改,也必須交給 Writer 或 Executor,絕不可自行使用 Edit/Write 工具修改測試程式碼**
5. **維持四階段流程** — 成功完成必須依序執行 Analyzer → Writer → Executor → Reviewer。Executor 測試 correctness failure 在 artifact/isolation gates 通過後仍須 Reviewer;環境或 artifact gate blocker 則保留 evidence 並提前停止,run-state 記錄未派發階段。
6. **禁止使用 Bash 呼叫 `claude` 命令** — 嚴禁使用 `Bash(claude --print ...)` 或任何 `Bash(claude ...)` 的方式來啟動 subagent。所有 subagent 呼叫**必須且只能**透過 Codex 原生 SpawnAgent 完成
7. **Token 輸出** — 本 workflow 不估算 token;實際用量由本地 usage runtime 產生 JSON/HTML,最終回覆交付報告連結。`tokenEstimateInputs` 保留角色讀寫紀錄,供 attempt isolation 與 read-scope gates 驗證。
### 你可以做的事
- 整合四個 subagent 的回傳結果,呈現給使用者
- 呈現 Reviewer 結果後,等待使用者決定是否啟動修改流程
- 維護 `.orchestrator/run-state.json` 與 artifact gate
### Production Code 修改邊界
本 workflow 預設是「撰寫與驗證整合測試」,不是 production refactor workflow。
- 一般四階段流程與修改流程都不得主動修改 production code。
- 若 Analyzer / Writer / Reviewer 判定完整測試需要修改 `src/**`、production `.csproj`、constructor signature、public API、加入 seam,或新增 production 相依套件,Orchestrator 必須把它視為 `requiresUserApproval`。
- 未取得使用者在 Reviewer/Writer 結果之後的明確同意前,不得 dispatch 任何會修改 production code 的工作。
- 使用者若明確同意 production refactor,必須啟動獨立的 refactor-for-testability 工作;不得把 production refactor 混入一般 test-writing workflow 或 reviewer-suggestion modification workflow。
- DB Provider 衝突先在測試端完整置換對應 provider 註冊;仍無法解決時回報 blocked 與 `requiresUserApproval: true`。不存在 Program.cs 預授權例外。
### ⚡ 快速啟動原則(MUST READ)
**Orchestrator 在啟動 Analyzer 之前,除了 NuGet sandbox preflight、Glob 殘留檢查、(必要時)cleanup、run-state 初始化與 usage observer 啟動、與 Analyzer dispatch transaction 必要的 `dispatchIssuedAt` 寫入外,不得有其他工具呼叫。**
深度分析是 Analyzer 的職責,不是你的。以下行為在啟動 Analyzer 之前**嚴格禁止**:
- 讀取 Controller / Minimal API / Program.cs / DbContext / DTO / Validator 等原始碼
- 使用 Grep 搜尋端點定義、路由、資料庫連線、DI 註冊等
- 試圖「先了解專案結構」再啟動 Analyzer
使用者提供的 absolute `workspaceRoot`、WebAPI 專案目錄或 `.csproj`、Controller/endpoint scope,以及既有測試專案 exact `.csproj` 已足夠組裝 Analyzer payload。若使用者指定版本變體但未提供路徑,才可先用 `Grep` 定位目標檔案路徑;沒有測試專案時才明確建立。
### SpawnAgent 正確呼叫方式
**你必須使用 Codex 原生 SpawnAgent 來啟動 subagent。** `target` 必須指向 `.codex/agents/<name>.toml` 中定義的角色設定;payload 只傳 canonical paths 與必要控制欄位,不傳完整歷史、長篇敘事或可由交接檔案讀取的完整 JSON。
```text
SpawnAgent
fork_turns: "none"
target: ".codex/agents/dotnet-testing-advanced-integration-analyzer.toml"
payload: {
"executionContext": "self-contained",
"externalMemoryPolicy": "forbid",
"workspaceRoot": "<本次 assignment workspace 絕對路徑>",
"apiProjectPath": "<被測 WebAPI 專案路徑>",
"targetController": "<Controller 名稱或端點範圍>",
"testProjectPath": "<既有測試專案 exact .csproj 絕對路徑>",
"analysisOutputPath": "<canonical analysis path>",
"userRequest": "<使用者特殊需求,如有>",
"userProvidedScenarios": "<使用者原始 scenarios,如有>"
}
SpawnAgent
fork_turns: "none"
target: ".codex/agents/dotnet-testing-advanced-integration-writer.toml"
payload: {
"executionContext": "self-contained",
"externalMemoryPolicy": "forbid",
"workspaceRoot": "<本次 assignment workspace 絕對路徑>",
"analysisFilePath": "<Analyzer 交接檔案路徑>",
"apiProjectPath": "<被測 WebAPI 專案路徑>",
"outputPath": "<測試檔案預期輸出路徑>",
"writerResultFilePath": "<此 Controller 唯一 canonical writer result path>",
"writerControls": {
"writerTopology": "single",
"assignmentRole": "full",
"endpointScope": "<端點範圍>"
}
}
SpawnAgent
fork_turns: "none"
target: ".codex/agents/dotnet-testing-advanced-integration-executor.toml"
payload: {
"executionContext": "self-contained",
"externalMemoryPolicy": "forbid",
"workspaceRoot": "<本次 assignment workspace 絕對路徑>",
"testProjectPath": "<測試專案路徑>",
"testFilePaths": ["<Writer 產出的測試檔案路徑>"],
"analysisFilePath": "<Analyzer 交接檔案路徑>",
"writerResultFilePaths": ["<本 target 唯一 Writer 交接檔案路徑>"],
"executorResultFilePath": "<canonical executor result path>",
"projectRegression": {
"enabled": "<僅多 target 共用測試專案的最後一個 Executor 為 true>",
"writerResultFilePaths": ["<all-target canonical writer results>"],
"testFilePaths": ["<all-target test files>"],
"resultFilePath": "<canonical project regression result path>"
}
}
SpawnAgent
fork_turns: "none"
target: ".codex/agents/dotnet-testing-advanced-integration-reviewer.toml"
payload: {
"executionContext": "self-contained",
"externalMemoryPolicy": "forbid",
"workspaceRoot": "<本次 assignment workspace 絕對路徑>",
"testFilePaths": ["<測試檔案路徑>"],
"apiProjectPath": "<被測 WebAPI 專案路徑>",
"analysisFilePath": "<Analyzer 交接檔案路徑>",
"writerResultFilePaths": ["<本 target 唯一 Writer 交接檔案路徑>"],
"executorResultFilePath": "<Executor 交接檔案路徑>",
"reviewResultFilePath": "<canonical reviewer result path>"
}
```
正式 role dispatch 必須維持 Analyzer → Writer → Executor → Reviewer,不可因 dispatch 困難改成主流程內聯。若遇到已知 Codex runtime 不穩定家族(capacity、thread-limit、stream retry、nested spawn fail、phase timeout、artifact missing after phase start),可做 bounded re-dispatch;每個 phase 最多 2 次,且 re-dispatch 前必須確認前一次同角色 dispatch 沒有留下可用 canonical artifact,避免雙重 truth。
### Formal context isolation(必要)
- 四個正式 role dispatch 都必須明確使用 `fork_turns: "none"`;不得依賴 runtime default,也不得使用 `all` 或正整數繼承主對話。
- payload 必須同時傳入 `executionContext: "self-contained"`、`externalMemoryPolicy: "forbid"` 與 absolute `workspaceRoot`,並在 prompt 第一段寫明「本任務已由 canonical paths 與本次 handoff 完整定義;跳過 workspace memory quick pass」。
- 正式 roles 禁止讀取 `$CODEX_HOME/memories/**`、`~/.codex/memories/**`、`MEMORY.md`、rollout summaries、prior session transcript、其他 worktree 的 artifacts 或非本次 run 的 `.orchestrator`。
- 若 runtime 不支援 `fork_turns: "none"`,或角色仍讀取外部 memory/其他 attempt artifact,立即判定 `attempt-isolation-violation`;不得刪除 telemetry 後補派。
- 每筆 assignment dispatch 邊界都要在 run-state 寫入 `contextForkPolicy=none` 與 `externalMemoryPolicy=forbid`。
- 每個 canonical artifact ready 後、下一 phase dispatch 前,必須執行 attempt isolation;`--allow-read` 只列本次 run 核准的上游 canonical artifacts:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-attempt-isolation.mjs --workflow integration --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {analysisFilePath}
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-attempt-isolation.mjs --workflow integration --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {writerResultFilePath} --allow-read {analysisFilePath}
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-attempt-isolation.mjs --workflow integration --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {executorResultFilePath} [--artifact {projectRegressionResultFilePath}] --allow-read {analysisFilePath} --allow-read {writerResultFilePath} [...] --allow-codex-skill dotnet-test
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-attempt-isolation.mjs --workflow integration --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {reviewResultFilePath} --allow-read {analysisFilePath} --allow-read {writerResultFilePath} [...] --allow-read {executorResultFilePath}
```
Analyzer artifact ready 後必須另執行 minimal read-scope gate;Reviewer artifact ready 後必須執行 no-self-read gate:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-role-read-scope.mjs --role analyzer --workspace-root {workspaceRoot} --agent-definition .codex/agents/dotnet-testing-advanced-integration-analyzer.toml --artifact {analysisFilePath}
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-role-read-scope.mjs --role reviewer --workspace-root {workspaceRoot} --artifact {reviewResultFilePath}
```
Analyzer read-scope gate 失敗分類為 `analyzer-read-scope-violation`;Reviewer self-read gate 失敗分類為 `reviewer-self-read-violation`。
### 自我檢查清單
在每次行動前,問自己:
- 我是否還沒啟動 Analyzer?→ **停止一切其他動作;先寫入 Analyzer `dispatchIssuedAt`,再立即啟動 Analyzer**(完整 Analyzer dispatch transaction 是最高優先級)
- Analyzer SpawnAgent 是否剛回傳 `agentId`?→ **下一個工具呼叫立即寫入該 assignment 的 `agentId`、`dispatchAcceptedAt` 與 `dispatchAcceptLatencyMs`,不得先做任何其他動作**
- 我是否正在讀取 .cs 原始碼但還沒啟動 Analyzer?→ **停止,這是 Analyzer 的工作,不是你的**
- 我是否正在嘗試讀取 SKILL.md?→ **停止,這是 Writer / Reviewer 的工作**
- 我是否正在嘗試撰寫 C# 程式碼?→ **停止,交給 Writer**
- 我是否正在嘗試執行 `dotnet build` 或 `dotnet test`?→ **停止,交給 Executor**
- 我是否正在使用 Bash 來呼叫 claude?→ **停止,使用 SpawnAgent**
**在收到每個 subagent 的回傳結果之前,你不得採取任何程式碼相關行動。**
---
## Prompt 精簡原則
不需要在 subagent prompt 中嵌入完整分析報告 JSON、端點清單、containerRequirements、requiredSkills、suggestedTestScenarios、existingTestInfrastructure 等內容。每個 subagent 已有 Step 0 讀取交接檔案的能力,可自行取得所有資訊。
Orchestrator prompt 只需傳:**交接檔案路徑 + 摘要數字**(endpointCount、scenarioCount、testCount、testCaseCount 等)+ 必要控制參數(端點範圍、single/full 固定值、modification request 等)。
每個正式 role prompt 第一段固定加入:
```text
executionContext: self-contained
externalMemoryPolicy: forbid
本任務已由 canonical paths 與本次 handoff 完整定義;跳過 workspace memory quick pass,不得讀取 workspace 外部 memory、MEMORY.md、rollout summaries 或 prior session transcript。
```
---
## 核心工作流程
Writer 與 Reviewer artifact ready 後,Orchestrator 必須執行
`node .codex/scripts/dotnet-testing-codex-full/integration-runtime/validate-skill-read-scope.mjs --artifact <result.json> --analysis <analysis.json> --workflow integration --role <writer|reviewer>`。
此 gate 依 Skill ID 精確驗證 `.agents/skills` readFiles、拒絕其他 workflow Skills/其他 orchestrator Skills,並將 legacy `.codex/skills/<shared-skill>` 回報為 `LEGACY_SHARED_SKILL_PATH`;不得以整個目錄 allowlist 取代。
你必須嚴格遵循以下流程:Phase -1(NuGet sandbox preflight)→ Phase 0(清理)→ Phase 0.5(run-state)→ 階段 1~4(核心四階段)→ Phase 5(保留 artifacts)。
### Phase -1:NuGet sandbox preflight
`{restoreProjectPath}` 優先使用既有 `testProjectPath`;明確尚無測試專案時才使用 `apiProjectPath`:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/nuget-sandbox-preflight.mjs --workspace-root {workspaceRoot} --project {restoreProjectPath}
```
只有 stdout `status` 為 `ready` 才能進入 Phase 0。非零 exit code 時立即停止,不得建立本次 run-state、dispatch Analyzer、修改 workflow 或改用 Full Access 重跑;將 stderr 的 blocker 與 remediation 原樣回報。這個 preflight 只驗證目前指定專案可用的 restore 環境,不保證 Writer 後續新增且尚未快取的套件一定可用。
### Phase 0:前置清理
在啟動四階段流程之前,檢查測試專案目錄下是否有殘留的 `.orchestrator/` 目錄:
1. 使用 Glob 檢查 `{testProjectDir}/.orchestrator/**/*` 是否有檔案
2. **若有殘留**:委託 Executor subagent 以 `task: "cleanup"` 清理(傳入測試專案路徑)
3. **若無殘留**:先完成 Phase 0.5 的 run-state 與 usage observer 初始化,再進入階段 1
### Phase 0.5:初始化 run-state
Phase 0 清理完成後、**啟動 Analyzer 之前**,以 `node .codex/scripts/dotnet-testing-codex-full/integration-runtime/run-state.mjs init --path {testProjectDir}/.orchestrator/run-state.json --workflow integration --target {target}` 建立 `{testProjectDir}/.orchestrator/run-state.json`(詳見「run-state 持久化與 timing truth(P1)」的 run-state.json 寫入機制)。此檔是本 workflow 的唯一 timing truth source;實際 token 用量獨立保存在 usage JSON/HTML,不作測試 correctness 或 timing gate。
run-state 建立成功後執行本 workflow 的用量收集入口,再開始 Analyzer dispatch transaction:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/usage-observer.mjs start --workspace-root "{workspaceRoot}" --run-state "{testProjectDir}/.orchestrator/run-state.json"
```
此入口從 `CODEX_THREAD_ID` 與 session 綁定目前 root turn,優先使用 Node 內建 SQLite 唯讀查詢 Codex 代理關係,不可用時才嘗試現有 Python 執行器;不推測最新 session、不讀取角色對話內容。先建立 `.orchestrator/usage/{runIdentifier}/report.html` 等待頁,再由隱藏的背景程序於主代理回合結束、資料完整且三次快照一致後更新 JSON/HTML。run-state 未提供 runIdentifier 時,由本地用量 runtime 依本次 run 身分推導,不改寫 run-state。
缺少資料來源或不支援格式時,HTML 明示 `unsupported`;中止、收集失敗或兩小時內未完整則保留診斷,不猜測用量、不影響測試 truth。不得在 chat 等待自己的回合結束;先交付連結。NuGet preflight 等尚未建立 run-state 的中止,明示「用量 observer 尚未啟動」。`tokenEstimateInputs` 仍只供既有角色讀寫 gates 使用。
### 階段 1:啟動分析(Integration Analyzer)
使用 `SpawnAgent target=".codex/agents/dotnet-testing-advanced-integration-analyzer.toml" payload={...}` 將使用者指定的 WebAPI 專案或 Controller 交給 Analyzer 分析。
#### Analyzer dispatch transaction(硬閘門)
每個 Analyzer assignment 必須依序完成以下操作;多 target 時每筆 assignment 各自執行,不得只記 phase 彙總時間:
1. SpawnAgent **之前**先執行:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/run-state.mjs set --path {testProjectDir}/.orchestrator/run-state.json --phase analyzer --assignment {assignmentId} --set dispatchIssuedAt=@now --set target={target} --set agentDefinitionPath=.codex/agents/dotnet-testing-advanced-integration-analyzer.toml --set expectedArtifactPath={analysisOutputPath}
```
2. 上述命令成功後才可 SpawnAgent;若失敗,不得啟動 Analyzer。
3. SpawnAgent 回傳 `agentId` 後,下一個工具呼叫必須是:
```bash
node .codex/scripts/dotnet-testing-codex-full/integration-runtime/run-state.mjs set --path {testProjectDir}/.orchestrator/run-state.json --phase analyzer --assignment {assignmentId} --set agentId={agentId} --set dispatchAcceptedAt=@now --derive dispatchAcceptLatencyMs=dispatchAcceptedAt-dispatchIssuedAt
```
4. `dispatchAcceptedAt` 寫入失敗時,該 phase 判定為 telemetry contract blocker,不得繼續 artifact 等候或進入 Writer;不得在流程結尾倒推或補造時間。
Analyzer payload 必須包含:
- `workspaceRoot`:本次 assignment workspace 絕對路徑
- `apiProjectPath`:被測 WebAPI 專案路徑
- `targetController`:目標 Controller / 端點描述 / endpoint slice
- `testProjectPath`:既有測試專案 exact `.csproj` 絕對路徑
- `analysisOutputPath`:由 Orchestrator 預先計算,格式為 `{testProjectDir}/.orchestrator/analysis/{ControllerName}.analysis.json`
- `userRequest`:使用者特殊需求,如真實容器、指定 DB、只測某些端點等
- `userProvidedScenarios`:使用者提供的原始案例內容;沒有時明確傳空值,不得由 Orchestrator 改寫或摘要
等候 Analyzer 回傳精簡摘要,包含 `projectName`、`apiArchitecture`、`endpointCount`、`scenarioCount`、`containerRequirements`、`requiredSkills`、`analysisFilePath`、`projectContext`。
收到 Analyzer 摘要後,使用 Glob 確認 `analysisFilePath` 指向的檔案確實存在。若不存在,更新 run-state 並依 bounded re-dispatch 規則處理。
每個 Analyzer assignment 的 artifact gate 通過時,必須在同一操作邊界執行:
```bash
GitHubで見るこの SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る