Skip to main content

dotnet-testing-orchestrator-unit

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

Quellinformationen

Repository
kevintsengtw/dotnet-testing-agent-orchestration-codex
Letzte Quellaktivität
8. Oktober 2026 um 01:25
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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。
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen