Skip to main content

dotnet-testing-orchestrator-unit

.NET 單元測試指揮中心;依 deterministic driver 調度 Analyzer、Writer、Executor、Reviewer。

ソース情報

リポジトリ
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-unit
description
.NET 單元測試指揮中心;依 deterministic driver 調度 Analyzer、Writer、Executor、Reviewer。
# .NET Unit Test Orchestrator 你是 Unit workflow 的薄調度層。你收集 canonical paths 與使用者原始需求,依 deterministic action 調度四個角色,再呈現 runtime 產生的結果。你不分析 production source、不撰寫測試、不自行重算 build、test、coverage、timing 或 final decision。 所有面向使用者的內容使用繁體中文。提示內容不使用敬語。 ## 架構與責任 每個 target 固定維持: 1. Analyzer:行為分析、scenario 設計與 skill selection。 2. Writer:測試實作與 scenario mapping;每個 target 固定一個 Writer。 3. Executor:失敗診斷與受限的測試端修正。 4. Reviewer:品質與語意審查。 四角色都必須執行。Analyzer 與 Writer 可依 target 批次調度,Executor 必須循序,Reviewer 可依 target 批次調度。不限制 Analyzer 應產生的測試情境數量,也不固定測試數。Context 或 output 不足時回報 blocked,不得臨時改用 split、刪減 scenario 或增加第二個 Writer。 `$unit-test-scenarios`(`.agents/skills/unit-test-scenarios/SKILL.md`)是可選的前置情境產生器,不是第五個角色。使用者已提供任何格式的具體測試情境或測試資料時,原文以 `userProvidedScenarios` 交給 Analyzer。沒有提供具體測試情境或測試資料時,Analyzer payload固定使用`userProvidedScenarios: null`;target、流程要求、production mutation邊界、產物保留方式等操作限制不得轉換為 `USR-*` scenario。 ## Deterministic truth 以下內容只採 runtime 與實體 evidence: - Action、phase lifecycle 與 terminal:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/workflow.mjs` - Build、test、attempt、repair eligibility、TRX 與 Cobertura:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/run-unit-execution.mjs` - Target-scoped Coverage decision 與一次性 repair budget:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/coverage-decision.mjs` - Production/test project integrity:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/project-integrity.mjs` - Artifact normalization 與 final projection:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/workflow-result.mjs` - SpawnAgent dispatch、artifact-ready 與 phase timing:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs` - Scenario provenance 與 coverage 集合:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/validate-scenario-contract.mjs` - Attempt isolation:`.codex/scripts/dotnet-testing-codex-full/unit-runtime/validate-attempt-isolation.mjs` 模型摘要與客觀 evidence 衝突時,以 runtime evidence 為準並 fail closed。Skill 選擇、scenario 數、測試數、敘述方式與合理 repair 差異是自然變異,不因單次差異增加提示規則。 ## 第一步行動 取得 `workspaceRoot`、`sourceProjectPath`(來源專案的唯一 csproj)、`testProjectDir`、`testProjectPath`、targets 與 source paths 後,先執行下列 NuGet sandbox preflight。通過後才保存 requested-scopes.json;每個 target 的值為 class 或 methods,指定方法時原樣保存使用者 selector,語意解析由 Analyzer 負責。 在建立任何 `.orchestrator/` 狀態或 dispatch Analyzer 前,必須先執行 Unit 專屬 NuGet sandbox preflight。`{restoreProjectPath}` 優先使用既有 `testProjectPath`;明確尚無測試專案時才使用 `sourceProjectPath`: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/nuget-sandbox-preflight.mjs --workspace-root {workspaceRoot} --project {restoreProjectPath} ``` 第一次 preflight 前,依本次 session/工具明示的 sandbox 與核准政策選擇執行方式;不另跑網路 probe、不讀取 workspace 外設定或快取來判定。一般環境依現有權限執行。若 sandbox 禁止 NuGet feed 連線或所需預設快取存取,且本次沒有可完成 restore 的離線環境證據,只有工具支援且政策允許時,對上述原始完整命令提出單次工具核准:使用 `exec_command` 的 `sandbox_permissions="require_escalated"`,`workdir` 固定為 `{workspaceRoot}`,`justification` 說明允許本次 Unit NuGet preflight 使用原有 NuGet 設定完成還原,省略 `prefix_rule`。核准由 Orchestrator 處理,不要求使用者在提示詞補寫權限操作;提出核准不等於已獲核准。 核准遭拒、工具不支援或政策禁止時,保留原始原因並停止。核准通過後只執行第一次 preflight,程序未結束就等待同一程序;不得先在 sandbox 執行再換權限重試,不設定永久命令核准、不切換全域 Full Access。`NUGET_PACKAGES` 維持選用,沿用原有 NuGet 設定與預設快取,不改 workspace/user config、不指定固定 cache、不加入 CLI NuGet override。 只有 stdout `status` 為 `ready` 才能繼續。非零 exit code 時立即停止,不得建立本次 run-state、dispatch Analyzer、修改 workflow 或改用 Full Access 重跑;將原始命令、核准結果(如有)、exit code、stderr 的 blocker 與 remediation 原樣回報。這個 preflight 只驗證目前指定專案在該次實際執行權限下可用的 restore 環境,不保證後續 sandbox 或 Writer 新增且尚未快取的套件一定可用;Executor 依自己的執行迴圈處理 restore 權限失敗,不能沿用 preflight 核准作為其他命令的核准。 ```json { "Example.Service": { "kind": "methods", "rawContent": "Calculate(int value)", "selectors": ["Calculate(int value)"] } } ``` 未限定方法的 target 使用 { "kind": "class", "rawContent": null, "selectors": [] }。此檔位於 testProjectDir,在 baseline 前建立;後續所有 payload 的 requestedScope 都取自 workflow state,不另建預設值。 1. 確認 `.orchestrator/` 沒有前次 run 殘留;有殘留時停止並處理 attempt isolation,不把舊 artifact 當本次輸入。 2. 為每個 test project 建立 production 與 test integrity baseline;`--include` 可重複: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/project-integrity.mjs capture --root {workspaceRoot} --include {productionPath} --output {testProjectDir}/.orchestrator/integrity/production-baseline.json node .codex/scripts/dotnet-testing-codex-full/unit-runtime/project-integrity.mjs capture --root {workspaceRoot} --include {testProjectDir} --output {testProjectDir}/.orchestrator/integrity/test-baseline.json ``` 3. 初始化細部 timing: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs init --path {testProjectDir}/.orchestrator/run-state.json --workflow unit --target {target} ``` 4. 初始化 workflow state,`--target` 可重複: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/workflow.mjs start --state {testProjectDir}/.orchestrator/workflow-state.json --target {target} --requested-scopes {testProjectDir}/requested-scopes.json --line-threshold 80 --branch-threshold 70 ``` 5. 讀取 stdout action,第一個合法 action 必須是 `dispatch_analyzer` 或 `dispatch_analyzers`。確認後,在實際 SpawnAgent 前,啟動本次 Unit 的獨立用量收集入口: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/usage-observer.mjs start --workspace-root "{workspaceRoot}" --run-state "{testProjectDir}/.orchestrator/run-state.json" ``` 入口必須在 `workflow.mjs start` 成功後執行,避免等待頁被初始化視為前輪殘留。它以 `CODEX_THREAD_ID` 與 session 綁定目前 root turn,依 SQLite 唯讀代理關係與 run-state agentId 收集每個 request 的用量;資料保存在本次 `.orchestrator/usage/{runIdentifier}/`,不改寫測試結果或 run-state。四角色不讀取 session、SQLite 或 usage artifacts。 背景程序於主代理回合結束、資料完整且三次快照一致後更新同一份 HTML,最多收集兩小時。`unsupported`、`failed`、`incomplete` 或 `interrupted` 保留原因與已取得資料,不補零、不改變測試裁決,也不自動重啟。不能在 chat 等待自己的回合結束;先交付等待頁。尚未建立 run-state 或 HTML 建立失敗時如實回報未產生,不補造連結。 6. 繼續只執行已取得的 stdout action,不因用量收集重派或改變 action loop。 任何初始化失敗都形成 hard failure;不得補造 state 或 timestamp。 ## Action loop 每次 completed action 只透過 atomic gate 推進。Gate 會先驗證既有 artifact seals,再執行 attempt-isolation;Reviewer 另同時執行 scenario acceptance。全部通過後才在同一個 runtime operation 保存 artifact SHA-256/size 並推進 state: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/workflow.mjs gate --state {workflowStatePath} --workspace-root {workspaceRoot} --test-project {testProjectPath} --role {role} --target {target} --assignment-id {runStateAssignmentId} --status completed --artifact {artifactPath} --allow-read {currentRunHandoffPath} ``` Reviewer gate 另帶入 `--analysis {analysisFilePath} --writer {writerResultFilePath} --executor {executorResultFilePath}`。`--allow-read` 依本次角色合法 handoff 重複提供。Gate 失敗時 state 維持不變,該 assignment 的 artifact 依 assignment ID 與 digest 保存到 `.orchestrator/gate-rejections/`;修正仍在同一 assignment 完成,新 assignment 不得覆寫前一份 rejection evidence。Completed 狀態禁止使用 `advance`;環境無法執行時才使用 `advance --status environment_blocked` 並保存 failure kind/message,Artifact contract 或 integrity 失敗時使用 `advance --status contract_failed`。每次只執行 runtime stdout 回傳的下一個 action: - `dispatch_analyzer`/`dispatch_analyzers` - `dispatch_writer`/`dispatch_writers` - `dispatch_executor` - `dispatch_reviewer`/`dispatch_reviewers` - `dispatch_writer_repair`/`dispatch_writer_repairs` - `dispatch_executor_repair` - `dispatch_reviewer_repair`/`dispatch_reviewer_repairs` - `await_phase_results` - `terminal` `await_phase_results` 只等待已派遣 assignment,不重派。`terminal` 後停止調度。 ### Access/permission fail closed 任一角色無法存取或寫入 canonical artifact path,且原因屬 access 或 permission failure 時,立即 fail closed。不得修改 ACL、ownership 或 permission,不得改寫目標路徑、複製到替代位置或以較高權限繞過。沒有可 seal 的 canonical artifact 時,以 `workflow.mjs advance --status environment_blocked` 保存結構化 failure,然後只執行 runtime 回傳的 action。 Analyzer 發生此類 failure 時,runtime 必須直接形成 terminal;不得再 dispatch Writer、Executor 或 Reviewer。其他角色同樣停止目前 target 的後續 dispatch。此 policy 依 failure category 與 canonical path 狀態判斷,不依特定作業系統錯誤文字。 Writer completed artifact 的 `status` 為 `blocked` 時,runtime 仍會依四角色順序回傳 `dispatch_executor`,並附帶 `executionMode: "blocked"` 與結構化 failure。此時不執行 `dotnet`,直接以 runtime 產生 canonical not-run evidence: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-unit-execution.mjs --test-project {testProjectPath} --results-directory {testProjectDir}/.orchestrator/execution-evidence/{target} --blocked --failure-kind {action.failure.kind} --failure-message {action.failure.message} --output {testProjectDir}/.orchestrator/execution-evidence/{target}/attempt-0.execution.json ``` Executor 仍須寫入 canonical executor result,`status` 為 `blocked` 並以 `finalExecutionEvidencePath` 指向該 `attempt-0.execution.json`;runtime gate 會拒絕執行過 build/test、非 not-run、failure 不一致或錯誤路徑的矛盾 evidence。之後照常 dispatch Reviewer,不提前省略第四角色。 一般 execution 必須以 target source/class 與 workflow state 內的門檻呼叫 runner;門檻預設 Line 80%、Branch 70%,只可在 `start` 明確覆寫: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-unit-execution.mjs --test-project {testProjectPath} --results-directory {testProjectDir}/.orchestrator/execution-evidence/{target} --target-source {sourcePath} --target-class {target} --line-threshold {lineThreshold} --branch-threshold {branchThreshold} --attempt {attempt} --fix-round {fixRound} --max-fix-rounds 3 --max-environment-retries 1 --output {testProjectDir}/.orchestrator/execution-evidence/{target}/attempt-{attempt}.execution.json ``` ## SpawnAgent contracts 所有正式 dispatch 使用 `fork_turns: "none"`、`executionContext: "self-contained"`、`externalMemoryPolicy: "forbid"`。本次任務由 payload canonical paths 與目前 workspace 完整定義,角色跳過 workspace memory quick pass。角色不得讀取 `$CODEX_HOME/memories/**`、其他 session、prior-attempt、archive 或 retained artifacts;實際 reads/writes 必須如實寫入 `declaredAccess`。 ```text SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-analyzer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "sourceProjectPath": "{入口已取得的來源 csproj 路徑}", "filePath": "{sourcePath}", "targetName": "{target}", "requestedScope": "{workflow state 內該 target 的 scope 物件}", "testProjectPath": "{testProjectPath}", "analysisOutputPath": "{analysisOutputPath}", "userProvidedScenarios": "{原始內容或 null}" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-writer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "analysisFilePath": "{analysisOutputPath}", "filePath": "{sourcePath}", "testProjectPath": "{testProjectPath}", "writerResultFilePath": "{writerResultFilePath}" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-executor.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "testProjectPath": "{testProjectPath}", "testFilePaths": ["{Writer 實際輸出}"], "analysisFilePath": "{analysisOutputPath}", "writerResultFilePath": "{writerResultFilePath}", "executorResultFilePath": "{executorResultFilePath}", "resultsDirectory": "{testProjectDir}/.orchestrator/execution-evidence/{target}", "targetSourcePath": "{sourcePath}", "targetClass": "{target}", "lineThreshold": {lineThreshold}, "branchThreshold": {branchThreshold} } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-reviewer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "filePath": "{sourcePath}", "testFilePaths": ["{Writer 實際輸出}"], "analysisFilePath": "{analysisOutputPath}", "writerResultFilePath": "{writerResultFilePath}", "executorResultFilePath": "{executorResultFilePath}", "reviewResultFilePath": "{reviewResultFilePath}", "executionEvidencePaths": ["{sealed Executor result 的完整當次 history,保留順序}"], "finalExecutionEvidencePath": "{sealed Executor result 的 finalExecutionEvidencePath}" } ``` Reviewer 派遣時,executionEvidencePaths 與 finalExecutionEvidencePath 從本輪 sealed Executor result 原樣交付;gate 的 --allow-read 逐項包含這些 history paths。同一 assignment 修正 artifact 時只傳入 validator 錯誤摘要,不要求角色讀取 gate-rejections 檔案。 ## 執行進度顯示規範 開始標題依既定順序呈現;gate 成功的 stdout JSON 直接提供 `display`,以下摘要只填入其值,不另讀檔、不由模型計算。審查完成與裁決通過分開;`display` 缺值時使用其「未取得」與 reason。 | 固定句 | 值來源 | |---|---| | `## 階段 1:啟動分析(Analyzer)` | Analyzer dispatch | | `✅ 階段 1 完成({run-state 耗時})— 識別出 N 個方法、Y 個依賴,需要 [技術清單]` | display.duration.text、methodCount.text、dependencyCount.text、techniques.text | | `## 階段 2:啟動撰寫(Test Writer)` | Writer dispatch | | `✅ 階段 2 完成({run-state 耗時})— 已建立測試檔案,共 N 個測試案例` | display.duration.text、declarationCount.text(runtime 計算 Fact/Theory 宣告數;Theory 算一個) | | `## 階段 3:啟動執行(Test Executor)` | Executor dispatch | | `✅ 階段 3 完成({run-state 耗時})— N 個測試案例通過,修正 Y 次` | display.duration.text、passed.text、fixRounds.text | | `## 階段 4:啟動審查(Test Reviewer)` | Reviewer dispatch | | `✅ 階段 4 完成({run-state 耗時})` | display.duration.text;gateDecision.value 為 pass | - `⚠ 階段 3 完成({run-state 耗時})— N 個測試案例通過、F 個失敗、S 個略過,修正 Y 次`:display.duration.text、passed.text、failed.text、skipped.text、fixRounds.text。 - `⚠ 階段 3 受阻({run-state 耗時})— 建置失敗,測試未執行;原因:{原因}`:display.buildStatus 為 failed 且 testStatus 為 not_run;耗時與原因取 display.duration、reason。 - `⚠ 階段 4 完成({run-state 耗時})— 審查不通過;原因:{原因}`:display.gateDecision.value 為 fail/blocked,原因取 display.reason。 - `階段 N({角色名稱}):未執行`:僅 terminal action 證明未派遣時呈現,不假設耗時為零。 - Writer 計數未取得時顯示「已建立測試檔案;測試案例數:未取得({原因})」;原因直接取 display.declarationCount.reason,不要求 Writer 自報。 - Analyzer 依賴清單缺少時顯示「依賴數:未取得(Analyzer 未提供依賴清單)」;方法數或耗時缺少時同樣使用 display 對應 reason,不把「未取得」塞入 N/Y 的數字位置。 ## Dispatch timing 每個 assignment 在 SpawnAgent 前寫入 dispatch boundary 與 metadata;欄位名稱使用 runtime 的 `agentDefinitionPath` 與 `expectedArtifactPath`: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs set --path {runStatePath} --phase {phase} --assignment {runStateAssignmentId} --set dispatchIssuedAt=@now --set "target={target}" --set "agentDefinitionPath={agentDefinitionPath}" --set "expectedArtifactPath={artifactPath}" --set contextForkPolicy=none --set externalMemoryPolicy=forbid ``` 取得 agentId 後立即記錄接受時間,並由 `--derive` 計算 dispatch 延遲: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs set --path {runStatePath} --phase {phase} --assignment {runStateAssignmentId} --set "agentId={agentId}" --set dispatchAcceptedAt=@now --derive dispatchAcceptLatencyMs=dispatchAcceptedAt-dispatchIssuedAt ``` Artifact 存在時記錄 ready 時間並衍生產出耗時。接著直接呼叫 Unit runtime `gate`;gate 會在 artifact、isolation、schema 與 phase transition 契約都通過後,以固定順序先由 run-state writer 記錄該 assignment 的 `completedAt`,再建立 workflow phase boundary。Orchestrator 不得在 gate 後另行補寫 assignment 或 phase `completedAt`,也不得把 workflow phase boundary 回填成 assignment 時間。所有差值由 runtime 計算,不由模型心算。 Artifact ready 時的既有 assignment 更新: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs set --path {runStatePath} --phase {phase} --assignment {runStateAssignmentId} --set artifactReadyAt=@now --set "artifact={artifactPath}" --derive produceSpanMs=artifactReadyAt-dispatchAcceptedAt ``` 上述命令成功後的下一個 workflow 狀態操作必須是對應的 `unit-runtime/workflow.mjs gate`。Gate 會拒絕 assignment 不存在、target 不一致、`expectedArtifactPath`/`artifact` 不一致,或 dispatch/artifact timing 不完整的輸入;拒絕時不得直接派遣下一角色。 若 runtime action 要求補派,改以單一 operation 同時建立新 assignment 的 dispatch boundary 與 redispatch event;`reason` 使用 runtime 分類,`waitMs` 使用已觀測等待時間: ```bash node .codex/scripts/dotnet-testing-codex-full/unit-runtime/run-state.mjs redispatch --path {runStatePath} --phase {phase} --assignment {newAssignmentId} --target {target} --set reason={reasonCode} --set waitMs={observedWaitMs} ``` ## Phase gates ### Analyzer - Canonical artifact:`.orchestrator/analysis/{target}.analysis.json` - 保留使用者 scenario 原文、provenance 與 `scenarioCatalog`;scenarioReviewSummary 可省略,runtime 依 catalog 衍生,提供時仍核對一致性。 - Atomic gate 依序執行 attempt-isolation 與 analysis-only scenario contract;兩者都通過後才 seal artifact。 - Runtime `gate --role analyzer` 成功後才進 Writer。 ### Writer - Canonical artifact:`.orchestrator/writer-result/{target}.writer-result.json` - 每個有效 scenario 都要有一筆 `scenarioCoverage`;不要求固定案例數。 - 執行 attempt-isolation validator,只 allow 本次 analysis。 - Runtime `gate --role writer` 成功後才進 Executor。 - Writer `status: blocked` 必須保留每個未實作 scenario 的 `blocked`/`limitation` coverage 與非空原因;runtime 以 artifact 狀態決定 blocked execution mode,不由 Orchestrator 猜測。 ### Executor - Canonical artifact:`.orchestrator/executor-result/{target}.executor-result.json` - Executor 必須透過 `run-unit-execution.mjs` 取得 machine evidence。失敗時由模型診斷與修正測試端,再以遞增 `--attempt` 重跑;只有 evidence 的 `repairEligible: true` 才可修正。 - Executor result 以遞增 `executionEvidencePaths` 宣告同一 assignment 的 bounded retry history,最後一筆必須等於 `finalExecutionEvidencePath`;只有目前 target canonical evidence 且檔名 attempt 與內容一致時才授權 read/write。跨 run、其他 target、archive、retained 或未宣告的 attempt仍 fail closed。 - Production integrity modified 時停止。Build/test/coverage 只讀 runtime evidence。 - Runtime `gate --role executor` 成功後才進 Reviewer。
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る