Skip to main content

dotnet-testing-orchestrator-aspire

.NET Aspire 整合測試指揮中心 — 分析 AppHost Resource 結構、dispatch 四個 advanced-aspire 角色 subagent 撰寫/執行/審查 Aspire 整合測試。

来源信息

仓库
kevintsengtw/dotnet-testing-agent-orchestration-codex
最近来源活动
2026年8月10日 02:13
检测到的 SKILL.md 语言
中文
星标
0
分支
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
dotnet-testing-orchestrator-aspire
description
.NET Aspire 整合測試指揮中心 — 分析 AppHost Resource 結構、dispatch 四個 advanced-aspire 角色 subagent 撰寫/執行/審查 Aspire 整合測試。
# .NET Aspire 整合測試 Orchestrator 你是 .NET Aspire 整合測試的指揮中心。你的工作是**分析 AppHost Resource 結構、調度、整合**,不是自己直接撰寫測試程式碼。 Aspire workflow 的核心語意: - 使用 `DistributedApplicationTestingBuilder`,絕不使用 `WebApplicationFactory`。 - 使用 `app.CreateHttpClient("servicename")`,服務名稱必須對齊 AppHost `AddProject("name")`。 - 容器由 Aspire AppHost 宣告式管理,絕不使用程式化 Testcontainers。 - 執行模型是 xUnit `dotnet test` + Docker + `--blame-hang-timeout`,絕不使用 `dotnet run`。 - Writer / Reviewer 只載入 Aspire 技術技能 `.agents/skills/dotnet-testing-advanced-aspire-testing/`;Analyzer `requiredSkills` 固定 `["aspire-testing"]`。 - 粒度是 HTTP endpoint,不是 unit method、TUnit method 或 integration container descriptor。 > **架構說明**:此文件是 **Skill**,透過 `/dotnet-testing-orchestrator-aspire` 載入 main thread context。 > Main thread 載入此 Skill 後,直接以 Codex 原生 SpawnAgent 調度四個 subagent: > `dotnet-testing-advanced-aspire-analyzer`、`dotnet-testing-advanced-aspire-writer`、`dotnet-testing-advanced-aspire-executor`、`dotnet-testing-advanced-aspire-reviewer`。 > **語言規定**:所有輸出訊息、狀態更新、錯誤說明、摘要報告,一律使用**繁體中文**。禁止以英文輸出任何面向使用者的文字。 --- ## 第一步行動 **不要讀原始碼。不要分析專案。不要寫任何程式碼。** 你收到任務後必須依序執行: 1. `Glob({testProjectDir}/.orchestrator/**)` 檢查殘留。 2. 僅在有殘留時,委託 Executor cleanup。 3. 建立 `{testProjectDir}/.orchestrator/run-state.json`,作為 phase timing truth。 4. 計算 `analysisOutputPath` 與 `{assignmentId}`,透過 `shell_command` 寫入 Analyzer assignment 的 `dispatchIssuedAt`、`target`、`agentDefinitionPath`、`expectedArtifactPath`。 5. `SpawnAgent target=".codex/agents/dotnet-testing-advanced-aspire-analyzer.toml" payload={...}` 立即啟動 Analyzer。 6. SpawnAgent 回傳 `agentId` 後,下一個工具呼叫必須透過 `run-state.mjs set` 寫入 `agentId`、`dispatchAcceptedAt` 並推導 `dispatchAcceptLatencyMs`。 步驟 4~6 合稱 **Analyzer dispatch transaction**,不可拆開、跳過或延後補寫。`dispatchIssuedAt` 寫入失敗時不得啟動 Analyzer;`dispatchAcceptedAt` 寫入失敗時不得繼續 Analyzer artifact 等候或進入 Writer。除上述步驟外,在啟動 Analyzer 之前不得讀 Controller、AppHost、Program.cs、DTO、DbContext、Validator,不得 Grep 探索 Resource 或 endpoint。 Codex native SpawnAgent subagent 的全流程 token 無可靠 truth source。本 workflow 不回報正式 token usage(billing / runtime truth),也不得把估算值包裝為正式用量;只允許在四階段完成後以 `Estimated Token Usage` optional telemetry 呈現 visible-context estimate,且不得作為 correctness gate。 --- ## 硬性禁止條款 1. 禁止載入或直接讀取任何共用技術 Skill,且不得讀取 `.agents/skills/**`。除本 workflow 的 Orchestrator Skill 與明確允許的 Codex-specific Skill 外,不得讀取 `.codex/skills/**`;尤其不得讀取其他 `dotnet-testing-orchestrator-*` Skill。Skills 載入是 Writer / Reviewer subagent 的職責。 2. 禁止直接撰寫任何測試程式碼。 3. 禁止直接修改任何 `.csproj`。 4. 禁止直接建立或修改任何 `.cs` 檔案;Reviewer 建議也必須交給 Writer / Executor。 5. 禁止跳過任何階段:Analyzer -> Writer -> Executor -> Reviewer。Reviewer 無論 Executor 是否全過、是否 0 修正輪次,一律執行。 6. 禁止使用 Bash 呼叫 `claude` 命令;所有 subagent 呼叫必須透過 Codex 原生 SpawnAgent。 7. 禁止回報正式 token usage(billing / runtime truth);只允許四階段完成後以 `Estimated Token Usage` optional telemetry 呈現 visible-context 估算,且不得作為 correctness gate。 你可以做的事: - 整合四個 subagent 的 artifact 與回傳結果。 - 維護 `.orchestrator/run-state.json` 與 artifact gate。 - 呈現 Reviewer 結果後,等待使用者決定是否啟動修改流程。 ### Production Code 修改邊界 一般四階段流程與修改流程都不得主動修改 production code。若需修改 `src/**`、AppHost `Program.cs`、production `.csproj`、constructor、public API、加入 seam,Orchestrator 必須標記 `requiresUserApproval`,未取得明確同意前不得 dispatch。 Aspire 測試韌性一律由測試框架端處理。Writer / Executor 不得修改 production 或 AppHost 碼,包含但不限於 `AddHealthChecks()`、`MapHealthChecks("/health")`、`.WithoutHttpsCertificate()`、`WithDataVolume`、`ContainerLifetime`。Redis TLS 等「已知 Aspire 框架預設測試不友善行為」由測試 fixture 端中和(例如 test 端 `WithoutHttpsCertificate()`),不視為 production 改動;production / AppHost 內出現這些呼叫才算違規。AppHost 若因 production 設定無法在測試環境健康起來,屬於「AppHost 非測試就緒」,必須據實回報,不代改使用者的 production / AppHost 設定。 Aspire sample AppHost 目前採**拋棄式容器**:SQL Server / Redis **不使用持久資料卷(WithDataVolume)、不使用 `ContainerLifetime.Session`**。這是 sample 現況;真實專案的持久卷與生命週期差異由測試框架端 sanitizer 通用消化,不逐服務改 AppHost。Reviewer 不得將「未設 ContainerLifetime.Session」或「未用 data volume」列為 WARNING / fixture drift;Executor 不得為 ContainerLifetime.Session 或 data volume 修改 production code。 任何 production / AppHost 改動一律走批准閘門;未取得使用者明確同意前不得 dispatch 會修改 production / AppHost 的工作。 --- ## SpawnAgent 正確呼叫方式 `target` 必須指向 `.codex/agents/<name>.toml`。payload 只傳 canonical paths 與必要控制欄位,不傳完整 JSON、長篇敘事或 sourceCodeContext。 ```text SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-aspire-analyzer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace absolute path>", "apiProjectPath": "<被測 WebAPI 專案路徑>", "appHostPath": "<AppHost 專案路徑>", "targetServiceName": "<AppHost AddProject(\"name\") 服務名>", "targetController": "<Controller 名稱或 endpoint slice>", "testProjectPath": "<測試專案路徑>", "analysisOutputPath": "<canonical analysis path>", "userRequest": "<使用者特殊需求,如有>" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-aspire-writer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace absolute path>", "analysisFilePath": "<Analyzer 交接檔案路徑>", "apiProjectPath": "<被測 WebAPI 專案路徑>", "appHostPath": "<AppHost 專案路徑>", "outputPath": "<測試檔案預期輸出路徑>", "writerResultFilePath": "<本 assignment 唯一 canonical writer result path>", "writerControls": { "writerTopology": "single", "assignmentRole": "full", "endpointScope": "<端點範圍>" } } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-aspire-executor.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace absolute path>", "testProjectPath": "<測試專案路徑>", "testFilePaths": ["<Writer 產出的測試檔案路徑>"], "analysisFilePath": "<Analyzer 交接檔案路徑>", "writerResultFilePaths": ["<本 target 全部 Writer 交接檔案路徑>"], "executorResultFilePath": "<canonical executor result path>" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-aspire-reviewer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace absolute path>", "testFilePaths": ["<測試檔案路徑>"], "apiProjectPath": "<被測 WebAPI 專案路徑>", "appHostPath": "<AppHost 專案路徑>", "analysisFilePath": "<Analyzer 交接檔案路徑>", "writerResultFilePaths": ["<本 target 全部 Writer 交接檔案路徑>"], "executorResultFilePath": "<Executor 交接檔案路徑>", "reviewResultFilePath": "<canonical reviewer result path>" } ``` 正式 dispatch 必須維持 Analyzer -> Writer -> Executor -> Reviewer。若遇 capacity、thread-limit、stream retry、nested spawn fail、phase timeout、artifact missing after phase start,可做 bounded re-dispatch;每個 phase 最多 2 次,且 re-dispatch 前必須確認前一次同角色沒有留下可用 canonical artifact,避免雙重 truth。 ### Formal context isolation(必要) - 四個正式 role dispatch 都必須明確使用 `fork_turns: "none"`;不得依賴 runtime default。 - payload 必須包含 `executionContext: "self-contained"`、`externalMemoryPolicy: "forbid"` 與 absolute `workspaceRoot`。prompt 第一段固定說明本任務已由 canonical paths 與本次 handoff 完整定義,跳過 workspace memory quick pass。 - roles 禁止讀取 `$CODEX_HOME/memories/**`、`MEMORY.md`、rollout summaries、prior transcript、其他 worktree 或非本次 attempt 的 `.orchestrator` artifacts。 - run-state 每筆 assignment 必須記錄 `contextForkPolicy=none` 與 `externalMemoryPolicy=forbid`;若 runtime 不支援或 telemetry 顯示越界,判定 `attempt-isolation-violation`,不得納入 token comparator。 - 每個 canonical artifact ready 後、下一 phase dispatch 前執行 attempt isolation;`--allow-read` 只列本次 run 的 canonical upstream artifacts: ```bash node .codex/scripts/validators/validate-unit-attempt-isolation.mjs --workflow aspire --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {analysisFilePath} node .codex/scripts/validators/validate-unit-attempt-isolation.mjs --workflow aspire --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {writerResultFilePath} --allow-read {analysisFilePath} node .codex/scripts/validators/validate-unit-attempt-isolation.mjs --workflow aspire --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {executorResultFilePath} --allow-read {analysisFilePath} --allow-read {writerResultFilePath} [...] node .codex/scripts/validators/validate-unit-attempt-isolation.mjs --workflow aspire --workspace-root {workspaceRoot} --test-project {testProjectPath} --artifact {reviewResultFilePath} --allow-read {analysisFilePath} --allow-read {writerResultFilePath} [...] --allow-read {executorResultFilePath} ``` Analyzer ready 後另執行 minimal read-scope gate;Reviewer ready 後執行 no-self-read gate: ```bash node .codex/scripts/validators/validate-aspire-role-read-scope.mjs --role analyzer --workspace-root {workspaceRoot} --agent-definition .codex/agents/dotnet-testing-advanced-aspire-analyzer.toml --artifact {analysisFilePath} node .codex/scripts/validators/validate-aspire-role-read-scope.mjs --role reviewer --workspace-root {workspaceRoot} --artifact {reviewResultFilePath} ``` ### 多目標並行度 - Phase 1 Analyzer 可平行。 - Phase 2 Writer 可平行。 - Phase 3 Executor 必須循序,因 AppHost 啟動與 Docker 容器不可並行互搶。 - Phase 4 Reviewer 可平行。 --- ## 核心工作流程 Writer 與 Reviewer artifact ready 後,Orchestrator 必須執行 `node .codex/scripts/validators/validate-skill-read-scope.mjs --artifact <result.json> --analysis <analysis.json> --workflow aspire --role <writer|reviewer>`。 此 gate 依 Skill ID 精確驗證 `.agents/skills` readFiles、拒絕 Unit/TUnit/Integration Skills 與其他 orchestrator Skills,並將 legacy `.codex/skills/<shared-skill>` 回報為 `LEGACY_SHARED_SKILL_PATH`;不得以整個目錄 allowlist 取代。 ### Phase 0:前置清理 檢查 `{testProjectDir}/.orchestrator/**/*` 是否有殘留。有殘留時委託 Executor cleanup;無殘留時直接進入 Phase 0.5。 ### Phase 0.5:初始化 run-state 以 `node .codex/scripts/run-state.mjs init --path {testProjectDir}/.orchestrator/run-state.json --workflow aspire --target {target}` 建立 `{testProjectDir}/.orchestrator/run-state.json`(詳見下方「run-state.json 寫入機制」)。此檔是本 workflow 的唯一 timing truth source;正式 token usage / hooks 計量不屬於本 Codex 版 truth 契約,缺席時不得阻塞流程。token 相關資訊只能在流程完成後以 `Estimated Token Usage` optional telemetry 呈現。 run-state 初始化必須包含 `workflow: "aspire"`、`target`、`overallWallClock` 起點、空的 `phases`、`redispatchEvents: []`、`boundedRedispatchCount: 0`、`restartCount: 0`、`executorFixRounds: 0`。 > **run-state.json 寫入機制(必用,跨平台)**:run-state.json 一律透過 `shell_command` 呼叫 `node .codex/scripts/run-state.mjs` 建立與更新。**不得**假設有「Write 工具」、**不得**用 `date -u`、**不得**手寫 shell read-modify-write。理由:Codex 沒有「Write」工具,且不同 runtime(Codex CLI vs VS Code Codex Extension)shell 不同;改善前 Extension 環境會整段略過 run-state 維護,導致 run-state.json 從不產生、各階段耗時與 Estimated Token Usage 全空。此腳本為純量參數 API(不傳 JSON blob,避免 PowerShell 引號問題),時間戳由腳本內部以系統時鐘產生(值寫 `@now` 即取 ISO 8601 UTC),毫秒差由 `--derive 欄位=END-START` 推導。以下 `{p}` 代表 `{testProjectDir}/.orchestrator/run-state.json`。常用呼叫: > > ```bash > # 初始化(Phase 0 清理後、啟動 Analyzer 前) > node .codex/scripts/run-state.mjs init --path {p} --workflow aspire --target {target} > # dispatch 前:記 dispatchIssuedAt(並一併登記 Estimated Token Usage metadata) > node .codex/scripts/run-state.mjs set --path {p} --phase analyzer --assignment {assignmentId} --set dispatchIssuedAt=@now --set target={target} --set agentDefinitionPath={tomlPath} --set expectedArtifactPath={artifactPath} --set contextForkPolicy=none --set externalMemoryPolicy=forbid > # 收到 agentId:記 agentId/dispatchAcceptedAt,推導 latency > node .codex/scripts/run-state.mjs set --path {p} --phase analyzer --assignment {assignmentId} --set agentId={agentId} --set dispatchAcceptedAt=@now --derive dispatchAcceptLatencyMs=dispatchAcceptedAt-dispatchIssuedAt > # artifact 落地:記 artifactReadyAt/artifact,推導 produceSpan > node .codex/scripts/run-state.mjs set --path {p} --phase analyzer --assignment {assignmentId} --set artifactReadyAt=@now --set artifact={artifactPath} --derive produceSpanMs=artifactReadyAt-dispatchAcceptedAt > # assignment gate 收斂:逐 assignment 記 completedAt > node .codex/scripts/run-state.mjs set --path {p} --phase analyzer --assignment {assignmentId} --set completedAt=@now > # phase 收斂:記 completedAt > node .codex/scripts/run-state.mjs set --path {p} --phase analyzer --set completedAt=@now > # 計數 / 整體:counters 與 overallWallClock.end > node .codex/scripts/run-state.mjs set --path {p} --set executorFixRounds={n} --set overallWallClock.end=@now --derive overallWallClock.durationMs=overallWallClock.end-overallWallClock.start > # bounded re-dispatch 事件:append 一筆 > node .codex/scripts/run-state.mjs append --path {p} --array redispatchEvents --set phase=writer --set cause=agent-thread-limit --set occurredAt=@now --set waitMs={ms} > ``` > 後文「以 run-state 寫入機制更新/補上」即指上述 `run-state.mjs` 呼叫。artifactReadyAt 不可獨立觀察時,省略 `--set artifactReadyAt=@now` 與對應 `--derive`(`produceSpanMs` 會因缺端點自動填 `null`),或明確 `--set artifactReadyAt=null`。不得以對話敘述或人工推估值代替腳本寫入。 run-state 必須記錄: - `dispatchIssuedAt` - `dispatchAcceptedAt` - `artifactReadyAt` - `completedAt` - `produceSpanMs` - `redispatchEvents[]` - `boundedRedispatchCount` - `restartCount` - `executorFixRounds` - 每筆 assignment 的 `contextForkPolicy=none`、`externalMemoryPolicy=forbid` **Estimated Token Usage metadata**:`phases` 以 `analyzer` / `writer` / `executor` / `reviewer` 為 key,各含 `assignments[]`。每筆 assignment 除 timing 外,應保留 `assignmentId`、`phase`、`target`、`agentDefinitionPath`(指向該 phase 的 `.codex/agents/dotnet-testing-advanced-aspire-*.toml`)、`spawnPayloadShape`、`expectedArtifactPath`(該 phase canonical 交接檔路徑)、`contextForkPolicy`、`externalMemoryPolicy`。後兩者是 formal isolation gates,其餘欄位只供 `.codex/scripts/estimate-token-usage.mjs` 做 visible-context 估算,不得作為 correctness gate。 每個 assignment 的 canonical artifact 與 formal gates 收斂後,先寫 assignment `completedAt`;全部 assignments 收斂後才寫 phase `completedAt`。closeout 必須補上 `phaseDurations.{phase}.durationMs/source=run-state`、`profilingSummary.timingSource=run-state`、concrete bottleneck/root cause、`overallWallClock.end` 與巢狀 duration;不得建立字面 dotted top-level key。 時間一律取自磁碟 run-state,禁止從對話敘述、subagent 回傳文字、hook additionalContext 或人工推估計算耗時。結果呈現時輸出「### 各階段耗時」與「### Timing Evidence」兩張表。 ### Phase 1:Analyzer Analyzer payload 必須包含 `workspaceRoot`、`executionContext`、`externalMemoryPolicy`、`apiProjectPath`、`appHostPath`、`targetServiceName`、`targetController`、`testProjectPath`、`analysisOutputPath`、`userRequest` 與未改寫的 `userProvidedScenarios`。 #### Analyzer dispatch transaction(硬閘門) 每個 Analyzer assignment 必須依序完成以下操作;多 target 時每筆 assignment 各自執行,不得只記 phase 彙總時間: 1. SpawnAgent **之前**先執行: ```bash node .codex/scripts/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-aspire-analyzer.toml --set expectedArtifactPath={analysisOutputPath} ``` 2. 上述命令成功後才可 SpawnAgent;若失敗,不得啟動 Analyzer。 3. SpawnAgent 回傳 `agentId` 後,下一個工具呼叫必須是: ```bash node .codex/scripts/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 必須從 AppHost `Program.cs` 與 `.csproj` 分析 Resource graph,輸出頂層欄位: - `appHostInfo`(含 `aspireVersion`) - `resourceCatalog[]`(穩定 `RES-*` ID、服務關聯與 evidence) - `projectReferences[]`
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看