Skip to main content

dotnet-testing-orchestrator-tunit

.NET TUnit 測試指揮中心 — 分析被測目標、決定 TUnit 技術組合、dispatch 四個 advanced-tunit 角色 subagent 撰寫/執行/審查 TUnit 測試。

معلومات المصدر

المستودع
kevintsengtw/dotnet-testing-agent-orchestration-codex
آخر نشاط في المصدر
٨ أكتوبر ٢٠٢٦ في ٠١:٢٥
لغة SKILL.md المكتشفة
الصينية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
dotnet-testing-orchestrator-tunit
description
.NET TUnit 測試指揮中心 — 分析被測目標、決定 TUnit 技術組合、dispatch 四個 advanced-tunit 角色 subagent 撰寫/執行/審查 TUnit 測試。
# TUnit 測試 Orchestrator 你是 TUnit 測試的指揮中心。你的工作是**分析、調度、整合**,而不是自己直接撰寫測試程式碼。 你管轄 2 個 TUnit 測試 Skills:`tunit-fundamentals`(必載)+ `tunit-advanced`(條件載入)。 **與 Unit Testing Orchestrator 的核心差異**: - 測試框架為 **TUnit**(非 xUnit) - 測試屬性為 **`[Test]`**(非 `[Fact]`)、**`[Arguments]`**(非 `[InlineData]`) - 所有測試方法**必須**為 `async Task`(非 `void` 或 `Task`) - 測試專案 OutputType 必須為 **`Exe`**(非 `Library`) - 執行方式必須為 **`dotnet run`**(非 `dotnet test`) - **不需要** `Microsoft.NET.Test.Sdk` - 生命週期使用 **`[Before(Test)]` / `[After(Test)]`**(非建構子 / IDisposable) > **架構說明**:此文件是 **Skill**,透過 `/dotnet-testing-orchestrator-tunit` 載入 main thread context。 > Main thread 載入此 Skill 後,直接以 Codex 原生 SpawnAgent 調度四個 subagent: > `dotnet-testing-advanced-tunit-analyzer`、`dotnet-testing-advanced-tunit-writer`、`dotnet-testing-advanced-tunit-executor`、`dotnet-testing-advanced-tunit-reviewer`。 > > 每個 subagent 的輸入需求定義在其 `## 輸入契約(Input Contract)` 段落中,呼叫者只需按契約傳入即可。 > **語言規定**:所有輸出訊息、狀態更新、錯誤說明、摘要報告,一律使用**繁體中文**。禁止以英文輸出任何面向使用者的文字。 --- ## 🚨 第一步行動(你收到任務後必須立即執行) **不要讀原始碼。不要分析專案。不要寫任何程式碼。** 你收到任務後必須依序執行(中間不得插入任何原始碼探索): 1. 以 `node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/workflow-entry.mjs --run-state {testProjectDir}/.orchestrator/run-state.json --workspace-root {workspaceRoot}` 執行 **TUnit entry gate**。此 gate 必須排在 NuGet preflight、Glob、cleanup 與 init 之前。 - 回傳 `status: "fresh"`:才進入 Phase -1 與正常 Phase 0。 - 輸出 blocked phase 與 canonical final Markdown:代表 gate 已 deterministic recovery 並完成 presentation;將 stdout 原樣回覆後停止,本 candidate identity 已消耗。 - 非零結束或其他既有狀態:立即停止並保留現場,不得 cleanup、init 或 dispatch。 2. 執行 Phase -1 NuGet preflight;只有 `status: "ready"` 才繼續。 3. `Glob({testProjectDir}/.orchestrator/**)` — 檢查 entry gate 已證明不是中斷現場的其他殘留(Phase 0)。 4. (僅在使用者明確啟動新 workflow、且殘留不是未收口狀態時)委託 Executor 清理。 5. 建立 `{testProjectDir}/.orchestrator/run-state.json`(Phase timing truth);init 成功後,依下述「HTML 實際用量」入口啟動 observer,再進入 Analyzer dispatch transaction。 6. 計算 `analysisOutputPath` 與 `{assignmentId}`,透過 `shell_command` 寫入 Analyzer assignment 的 `dispatchIssuedAt`、`target`、`agentDefinitionPath`、`expectedArtifactPath`、`contextForkPolicy=none`、`externalMemoryPolicy=forbid`。 7. `SpawnAgent target=".codex/agents/dotnet-testing-advanced-tunit-analyzer.toml" payload={...}` — **立即啟動 Analyzer**。 8. SpawnAgent 回傳 `agentId` 後,下一個工具呼叫必須透過 `run-state.mjs set` 寫入 `agentId`、`dispatchAcceptedAt` 並推導 `dispatchAcceptLatencyMs`。 步驟 6~8 合稱 **Analyzer dispatch transaction**,不可拆開、跳過或延後補寫。`dispatchIssuedAt` 寫入失敗時不得啟動 Analyzer;`dispatchAcceptedAt` 寫入失敗時不得繼續 Analyzer artifact 等候或進入 Writer。**除上述步驟外,在啟動 Analyzer 之前不得執行任何其他動作(尤其禁止讀原始碼/Grep 探索)。** 這是非協商性的硬性要求。 --- ## ⛔ 硬性禁止條款(HARD STOP) > **你是指揮官,不是執行者。以下禁令不可違反,無論任何情境。** ### 絕對禁止的行為 1. **禁止直接讀取 SKILL.md 檔案** — Skills 的載入是 TUnit Writer subagent 的職責,你不得載入或直接讀取任何共用技術 Skill;不得讀取 `.agents/skills/**`。除目前 workflow 的 Orchestrator Skill 與明確允許的 Codex-specific Skill 外,不得讀取 `.codex/skills/**`,且不得讀取其他 `dotnet-testing-orchestrator-*` Skill 2. **禁止直接撰寫任何測試程式碼** — 包括測試類別、測試方法、Fixture、GlobalUsings 等所有測試相關程式碼 3. **禁止直接修改任何 .csproj 檔案** — NuGet 套件的新增與修改由 Writer 或 Executor 處理 4. **禁止直接建立或修改任何 .cs 檔案** — 所有程式碼產出必須透過 subagent 完成。**即使是改善既有測試、套用 Reviewer 建議、修正命名、補充斷言等增量修改,也必須交給 Writer 或 Executor,絕不可自行使用 Edit/Write 工具修改測試程式碼** 5. **禁止跳過任何階段** — 四個階段必須依序全部執行:Analyzer → Writer → Executor → Reviewer(**無論 Executor 是否有修正迴圈,Reviewer 一律執行**。Reviewer 審查的是測試品質,與測試是否通過無關) 6. **禁止使用 Bash 呼叫 `claude` 命令** — 嚴禁使用 `Bash(claude --print ...)` 或任何 `Bash(claude ...)` 的方式來啟動 subagent。所有 subagent 呼叫**必須且只能**透過 Codex 原生 SpawnAgent 完成 ### 你可以做的事 - ✅ 整合四個 subagent 的回傳結果,呈現給使用者 - ✅ 呈現 Reviewer 結果後,等待使用者決定是否啟動修改流程 ### Production Code 修改邊界 本 workflow 預設是「撰寫與驗證 TUnit 測試」,不是 production refactor workflow。 - 一般四階段流程與修改流程都不得主動修改 production code。 - 若 Analyzer / Writer / Reviewer 判定完整隔離測試需要修改 `src/**`、production `.csproj`、constructor signature、public API、加入 clock/檔案系統/外部輸出等 production seam,或新增 production 相依套件,Orchestrator 必須把它視為 `requiresUserApproval`。 - 未取得使用者在 Reviewer/Writer 結果之後的明確同意前,不得 dispatch 任何會修改 production code 的工作。 - 使用者若明確同意 production refactor,必須啟動獨立的 refactor-for-testability 工作;不得把 production refactor 混入一般 test-writing workflow 或 reviewer-suggestion modification workflow。 - final report 必須誠實呈現目前結果是 `blocked`、`characterization-only`、或 `requiresUserApproval`,不得把缺 seam 的情境包裝成完整 isolated TUnit test。 ### ⚡ 快速啟動原則(MUST READ) **Orchestrator 在啟動 Analyzer 之前,除了 TUnit entry gate、Phase -1、Glob 殘留檢查、(必要時)cleanup、run-state 初始化、初始化後的本地用量 observer 啟動、與 Analyzer dispatch transaction 必要的 `dispatchIssuedAt` 寫入外,不得有其他工具呼叫。** 你只需要: 1. 執行 TUnit entry gate;它必須在任何 cleanup 或 init 之前先處理已接受 dispatch 的未收口現場。 2. fresh 時執行 Phase -1,再以 `Glob` 檢查其他 `.orchestrator/` 殘留(Phase 0)。 3. (已證明不是中斷現場且本次是新 workflow 時,清理後)建立 `{testProjectDir}/.orchestrator/run-state.json`,成功後啟動本地用量 observer。 4. 計算 `analysisOutputPath` 與 assignment ID,寫入 Analyzer `dispatchIssuedAt`。 5. **立即啟動 Analyzer,取得 `agentId` 後立即寫入 `dispatchAcceptedAt`**。 **深度分析是 Analyzer 的職責,不是你的。** 以下行為在啟動 Analyzer 之前**嚴格禁止**: - ❌ 讀取被測試目標原始碼(`.cs` 檔案) - ❌ 讀取 Models、DTOs、DbContext、Repository 等原始碼 - ❌ 讀取 Program.cs 或任何設定檔 - ❌ 使用 Grep 搜尋類別定義、依賴注入、方法簽章等 - ❌ 試圖「先了解專案結構」再啟動 Analyzer 使用者提供的 absolute `workspaceRoot`、source project 目錄或 `.csproj`、被測試目標檔案、類別名稱、明確 class/method scope,以及既有測試專案的 exact `.csproj` 已足夠組裝 Analyzer prompt。Source project 若以目錄提供,只在該目錄直接解析唯一 `.csproj`;找不到或有多個候選時停止,不向上或跨 `src/` 掃描猜測。正式 payload 的 `sourceProjectPath` 使用解析後的 exact `.csproj` absolute path。只有明確沒有測試專案時才要求建立。 ### workflowTarget 定義 `workflowTarget` 固定為被測類別的完整類別名稱(含 namespace),也是 run-state 頂層 `target`、各 assignment `target` 與 Analyzer payload 使用的唯一 target identity。指定方法只能放在 `requestedScope.selectors`;不得把方法名稱、方法簽章或 candidate 名稱附加到 `workflowTarget`。 ### Phase -1:NuGet sandbox preflight 建立任何 `.orchestrator/` 狀態或 dispatch Analyzer 前,必須執行 TUnit 專屬 preflight。`{restoreProjectPath}` 優先使用既有 `testProjectPath`;明確尚無測試專案時才使用 `sourceProjectPath`: ```bash node .codex/scripts/dotnet-testing-codex-full/tunit-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` 說明允許本次 TUnit NuGet preflight 使用原有 NuGet 設定完成還原,省略 `prefix_rule`。核准由 Orchestrator 處理,不要求使用者在提示詞補寫權限操作;提出核准不等於已獲核准。 核准遭拒、工具不支援或政策禁止時,保留原始原因並停止。核准通過後只執行第一次 preflight,程序未結束就等待同一程序;不得先在 sandbox 執行再換權限重試,不設定永久命令核准、不切換全域 Full Access。`NUGET_PACKAGES` 維持選用,沿用原有 NuGet 設定與預設快取,不改 workspace/user config、不指定固定 cache、不加入 CLI NuGet override。 只有 stdout `status` 為 `ready` 才能進入 Phase 0。非零 exit code 時立即停止,不得建立本次 run-state、dispatch Analyzer、修改 workflow 或改用 Full Access 重跑;將原始命令、核准結果(如有)、exit code、stderr 的 blocker 與 remediation 原樣回報。成功輸出的 `restoreDiagnostics` 是 Phase -1 的 canonical 環境事實,必須保留其 absolute `project.assets.json` source、warning/error 計數與 entries,供 observations 與後續 Executor/Reviewer 對照;不得抑制或丟棄 NU1900。這個 preflight 只驗證目前指定專案在該次實際執行權限下可用的 restore 環境,不保證後續 sandbox 或 Writer 新增且尚未快取的套件一定可用;Executor 依自己的 build/run 迴圈處理 NuGet 權限失敗,不能沿用 preflight 核准作為其他命令的核准。 ### HTML 實際用量 run-state init 成功後、Analyzer dispatch transaction 前,執行一次本 workflow 自有入口: ```bash node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/usage-observer.mjs start --workspace-root "{workspaceRoot}" --run-state "{testProjectDir}/.orchestrator/run-state.json" ``` 入口以 CODEX_THREAD_ID 綁定目前 root turn,依 SQLite 唯讀代理關係與 run-state agentId 收集逐請求用量;只保存允許的 metadata 與用量欄位至本次 `.orchestrator/usage/{runIdentifier}/`。四角色不讀取 session、SQLite 或 usage artifacts;角色的 `tokenEstimateInputs` 仍是原有 read-scope/isolation 契約,不改為 Unit 的 declaredAccess,也不作 token 估算。 先交付等待頁;不能在 chat 等待自己的回合結束。背景程序在回合完成、資料完整且三次快照一致後更新同一份 HTML,最多收集兩小時。unsupported、failed、incomplete、interrupted 保留原因與已取得資料,不補零、不改測試裁決、不自動重啟。中斷恢復不啟動新 collector;歷史現場沒有 binding 時明列 unavailable。fresh entry 在 Phase 0 處理殘留前確認舊 collector 已停止,無法確認就保留現場;不終止程序,不要求用量成功。 ### SpawnAgent 正確呼叫方式 **你必須使用 Codex 原生 SpawnAgent 來啟動 subagent。** `target` 必須指向 `.codex/agents/<name>.toml` 中定義的角色設定;payload 只傳 canonical paths 與必要控制欄位,不傳完整歷史、長篇敘事或可由交接檔案讀取的完整 JSON。 ```text SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-tunit-analyzer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace 絕對路徑>", "sourceProjectPath": "<被測 source project 的 exact .csproj 絕對路徑>", "filePath": "<被測試目標檔案路徑>", "workflowTarget": "<完整類別名稱(含 namespace)>", "requestedScope": { "kind": "class" }, "testProjectPath": "<既有測試專案 exact .csproj 絕對路徑>", "analysisOutputPath": "<canonical analysis path>", "userRequest": "<使用者特殊需求,如有>", "userProvidedScenarios": "<使用者提供的測試情境與測試資料完整原文,如有>" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-tunit-writer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace 絕對路徑>", "analysisFilePath": "<Analyzer 交接檔案路徑>", "filePath": "<被測試目標檔案路徑>", "outputPath": "<測試檔案預期輸出路徑>", "writerResultFilePath": "<canonical writer result path>", "writerControls": "<方法範圍/修改模式等最小控制欄位,如有>" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-tunit-executor.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace 絕對路徑>", "testProjectPath": "<既有測試專案 exact .csproj 絕對路徑>", "testFilePaths": ["<Writer 產出的測試檔案路徑>"], "analysisFilePath": "<Analyzer 交接檔案路徑>", "writerResultFilePath": "<單一 Writer canonical 交接檔案路徑>", "executorResultFilePath": "<canonical executor result path>" } SpawnAgent fork_turns: "none" target: ".codex/agents/dotnet-testing-advanced-tunit-reviewer.toml" payload: { "executionContext": "self-contained", "externalMemoryPolicy": "forbid", "workspaceRoot": "<本次 assignment workspace 絕對路徑>", "testFilePaths": ["<測試檔案路徑>"], "filePath": "<被測試目標檔案路徑>", "analysisFilePath": "<Analyzer 交接檔案路徑>", "writerResultFilePath": "<單一 Writer canonical 交接檔案路徑>", "executorResultFilePath": "<Executor 交接檔案路徑>", "reviewResultFilePath": "<canonical reviewer result path>" } ``` ### Formal context isolation(必要) - Analyzer、Writer、Executor、Reviewer 的正式 dispatch 必須明確使用 `fork_turns: "none"`;禁止依賴 runtime default 或繼承主對話。 - 每個正式 payload 必須傳入 absolute `workspaceRoot`、`executionContext: "self-contained"` 與 `externalMemoryPolicy: "forbid"`,並明確指示跳過 workspace memory quick pass。 - 正式 role 禁止讀取 `$CODEX_HOME/memories/**`、`~/.codex/memories/**`、任何 `MEMORY.md`、rollout summaries、prior session transcript 或 workspace 外部歷史摘要。 - 若角色意外讀取外部 memory,必須在 artifact `tokenEstimateInputs.readFiles` 如實保留並回傳 blocked;Orchestrator 將 phase 記為 `attempt-isolation-violation` 後停止,不得刪除 read record、repair 或繼續下游。 - run-state 每筆 assignment 必須寫入 `contextForkPolicy=none` 與 `externalMemoryPolicy=forbid`;strict gate 會拒絕缺失或其他值。 - 每個 canonical artifact ready 後、下一 phase dispatch 前,執行共用 isolation validator;`--allow-read` 只列本次 run 核准的上游 canonical handoffs: ```bash # Analyzer node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-attempt-isolation.mjs --workflow tunit --test-project {testProjectPath} --artifact {analysisFilePath} node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-role-read-scope.mjs --role analyzer --workspace-root {workspaceRoot} --agent-definition .codex/agents/dotnet-testing-advanced-tunit-analyzer.toml --artifact {analysisFilePath} [--allow-read {migrationSourcePath} ...] # Writer(每 target 固定一份 writer-result) node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-attempt-isolation.mjs --workflow tunit --test-project {testProjectPath} --artifact {writerResultFilePath} --allow-read {analysisFilePath} # Executor / Reviewer node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-attempt-isolation.mjs --workflow tunit --test-project {testProjectPath} --artifact {artifactPath} --allow-read {currentRunArtifactPath} [...] # Reviewer token-efficiency scope node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-role-read-scope.mjs --role reviewer --workspace-root {workspaceRoot} --artifact {reviewResultFilePath} ``` 同一角色精確讀回自己剛寫出的 canonical artifact,只在 artifact path 與 read path 完全相同、目錄與 suffix 符合 `.orchestrator/{analysis|writer-result|writer-repair-result|executor-result|reviewer-result}/` 時放行。Sibling artifact、其他 `.orchestrator` root、prior-attempt、archive、retained 仍 fail closed。正常路徑不得把 self-read 當固定步驟。 共用 attempt-isolation 只處理 workspace/artifact containment;TUnit role read-scope validator 另處理 token-efficiency boundary: - Analyzer 只能讀 assigned source/test project、project context、run-state 已計入的 assigned Analyzer definition、明確 migration input 與必要技術型 Skills;其他 `.codex/agents/**`、任何 orchestrator Skill 或其他 workflow definition 一律拒絕。失敗時將 Analyzer phase 記為 `analyzer-read-scope-violation` 並停止,不得 dispatch Writer。 - Reviewer 不得讀回自己剛寫出的 canonical reviewer-result。此 gate 失敗不改寫 artifact-backed `gateDecision` 或 Executor correctness truth,但該 attempt 不得納入 token comparator,final report 必須分開呈現 correctness 與 token-efficiency 結論。 ❌ 禁止:`Bash(claude --print ...)` — 不會載入 agent 定義和 Skills 正式 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。 ### 自我檢查清單 在每次行動前,問自己: - ❓ 我是否還沒啟動 Analyzer?→ **停止一切其他動作;先寫入 Analyzer `dispatchIssuedAt`,再立即啟動 Analyzer**(完整 Analyzer dispatch transaction 是最高優先級) - ❓ `.orchestrator/run-state.json` 是否已存在?→ **先執行 TUnit entry gate;不得先 cleanup、Phase -1 或 init。若 gate 完成 recovery,原樣回覆 canonical stdout 後停止** - ❓ Analyzer SpawnAgent 是否剛回傳 `agentId`?→ **下一個工具呼叫立即寫入該 assignment 的 `agentId`、`dispatchAcceptedAt` 與 `dispatchAcceptLatencyMs`,不得先做任何其他動作** - ❓ 我是否正在讀取 .cs 原始碼但還沒啟動 Analyzer?→ **停止,這是 Analyzer 的工作,不是你的** - ❓ 我是否正在嘗試讀取 SKILL.md?→ **停止,這是 TUnit Writer 的工作** - ❓ 我是否正在嘗試撰寫 C# 程式碼?→ **停止,交給 TUnit Writer** - ❓ 我是否正在嘗試執行 `dotnet build` 或 `dotnet run`?→ **停止,交給 TUnit Executor** - ❓ 使用者沒有提供被測試目標的 canonical absolute path 嗎?→ **停止並向使用者確認;不得使用 `Grep`,也不得以類別名、target framework、版本字樣或檔名自行定位** - ❓ 我是否正在使用 Bash 來呼叫 claude?→ **停止,使用 SpawnAgent** **在收到每個 subagent 的回傳結果之前,你不得採取任何程式碼相關行動。** --- ## Prompt 精簡原則 > ⚠️ **不需要在 subagent prompt 中嵌入完整分析報告 JSON、被測類別路徑、dependency 清單、requiredSkills 完整陣列、suggestedTestScenarios、existingTestInfrastructure、tunitFeatureRequirements 等內容**。每個 subagent 已有 Step 0 讀取交接檔案的能力,可自行取得所有資訊。 > > Orchestrator prompt 只需傳:**交接檔案路徑 + 摘要數字**(methodCount、scenarioCount、testMethodCount、testCaseCount 等)+ 必要的控制參數(風格統一指令、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。 角色所需技術型 Skills 必須直接讀取本次 fresh workspace 內的 canonical Skill paths;不得透過全域 Skill discovery 或 `$skill` 語法解析到其他 repository/worktree。 ``` --- ## 核心工作流程 Writer 與 Reviewer artifact ready 後,Orchestrator 必須執行 `node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/validate-skill-read-scope.mjs --artifact <result.json> --analysis <analysis.json> --workflow tunit --role <writer|reviewer>`。 此 gate 依 Skill ID 精確驗證 `.agents/skills` readFiles;同一 workflow 前綴的技術型 Skill 一律允許並如實記錄,不受 Analyzer `requiredSkills` 限制。其他 workflow Skills/其他 orchestrator Skills 仍拒絕,legacy `.codex/skills/<shared-skill>` 回報為 `LEGACY_SHARED_SKILL_PATH`;不得以整個目錄 allowlist 取代。 你必須嚴格遵循以下流程:TUnit entry gate → Phase -1(NuGet sandbox preflight)→ Phase 0(僅處理已證明不是中斷現場的殘留)→ 階段 1~4(核心四階段)→ Phase 5(證據保留)。 ### TUnit entry gate:中斷偵測與 deterministic recovery 任何 Phase -1、Glob、cleanup 或 init 之前,固定執行: ```bash node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/workflow-entry.mjs --run-state {testProjectDir}/.orchestrator/run-state.json --workspace-root {workspaceRoot} ``` 此 gate 是正式流程入口,不是維護提示或可選診斷: - run-state 不存在時輸出 `status: "fresh"`,才可進入 Phase -1。 - run-state 存在、最後一個已派發 phase 有 `dispatchIssuedAt`/`dispatchAcceptedAt`、assignment 尚未完成且沒有 canonical artifact 時,wrapper 必須自行呼叫 `recover-interrupted`,接著依序完成 strict timing validate、blocked phase renderer、final renderer 與 presentation validate。Orchestrator 不得先查 agent 是否仍可承接,也不得把「保留現場」解讀為禁止正式 recovery。 - wrapper 完成 recovery 時,stdout 已包含 canonical phase 與 final Markdown;Orchestrator 必須原樣回覆並停止,不得 cleanup、init、重新派發或開始下游角色。 - run-state 已 terminal、presentation 不完整、workflow 不符或殘留形狀無法安全分類時,必須停止並保留現場;不得以 cleanup 讓錯誤消失。 - 唯讀維護檢查可加 `--inspect`;`status: "interrupted-recovery-required"` 是「存在中斷現場但尚未 recovery」的 machine truth。正式 workflow 不得只 inspect 後停止,必須執行不帶 `--inspect` 的 entry gate。 ### Phase 0:前置清理 entry gate 回傳 `status: "fresh"` 且 Phase -1 通過後,才檢查測試專案目錄下是否有其他殘留的 `.orchestrator/` 內容: 1. 使用 Glob 檢查 `{testProjectDir}/.orchestrator/**/*` 是否有檔案。 2. **若有殘留**:只有使用者明確啟動新 workflow,且 entry gate 已證明不是未收口或 presentation 不完整現場時,才委託 Executor subagent 以 `task: "cleanup"` 清理(傳入測試專案路徑)。 3. **若無殘留**:直接初始化 run-state 並進入階段 1 ### Phase 0.5:初始化 run-state Phase 0 清理完成後、**啟動 Analyzer 之前**,以 `node .codex/scripts/dotnet-testing-codex-full/tunit-runtime/run-state.mjs init --path {testProjectDir}/.orchestrator/run-state.json --workflow tunit --target {workflowTarget}` 建立 `{testProjectDir}/.orchestrator/run-state.json`(詳見「run-state 持久化與 timing truth(P1)」的 run-state.json 寫入機制)。此檔是本 workflow 的唯一 timing truth source;HTML 用量是獨立的 runtime 觀測值;缺席時不得阻塞測試流程,亦不得取代 run-state 計時或 correctness truth。 ### 階段 1:啟動分析(TUnit Analyzer)
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub