universal-dev-standards 5.1.0-beta.6 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +6 -0
  2. package/bin/uds.js +14 -0
  3. package/bundled/ai/standards/agent-communication-protocol.ai.yaml +34 -0
  4. package/bundled/ai/standards/anti-sycophancy-prompting.ai.yaml +111 -0
  5. package/bundled/ai/standards/capability-declaration.ai.yaml +113 -0
  6. package/bundled/ai/standards/circuit-breaker.ai.yaml +93 -0
  7. package/bundled/ai/standards/developer-memory.ai.yaml +13 -0
  8. package/bundled/ai/standards/dual-phase-output.ai.yaml +108 -0
  9. package/bundled/ai/standards/failure-source-taxonomy.ai.yaml +115 -0
  10. package/bundled/ai/standards/frontend-design-standards.ai.yaml +305 -0
  11. package/bundled/ai/standards/health-check-standards.ai.yaml +140 -0
  12. package/bundled/ai/standards/immutability-first.ai.yaml +112 -0
  13. package/bundled/ai/standards/model-selection.ai.yaml +111 -3
  14. package/bundled/ai/standards/packaging-standards.ai.yaml +142 -0
  15. package/bundled/ai/standards/recovery-recipe-registry.ai.yaml +200 -0
  16. package/bundled/ai/standards/retry-standards.ai.yaml +134 -0
  17. package/bundled/ai/standards/security-decision.ai.yaml +87 -0
  18. package/bundled/ai/standards/skill-standard-alignment-check.ai.yaml +119 -0
  19. package/bundled/ai/standards/standard-admission-criteria.ai.yaml +107 -0
  20. package/bundled/ai/standards/standard-lifecycle-management.ai.yaml +144 -0
  21. package/bundled/ai/standards/timeout-standards.ai.yaml +104 -0
  22. package/bundled/ai/standards/token-budget.ai.yaml +108 -0
  23. package/bundled/ai/standards/translation-lifecycle-standards.ai.yaml +145 -0
  24. package/bundled/core/anti-sycophancy-prompting.md +184 -0
  25. package/bundled/core/capability-declaration.md +59 -0
  26. package/bundled/core/circuit-breaker.md +58 -0
  27. package/bundled/core/developer-memory.md +29 -1
  28. package/bundled/core/dual-phase-output.md +56 -0
  29. package/bundled/core/failure-source-taxonomy.md +72 -0
  30. package/bundled/core/frontend-design-standards.md +474 -0
  31. package/bundled/core/health-check-standards.md +72 -0
  32. package/bundled/core/immutability-first.md +105 -0
  33. package/bundled/core/model-selection.md +80 -0
  34. package/bundled/core/packaging-standards.md +216 -0
  35. package/bundled/core/recovery-recipe-registry.md +69 -0
  36. package/bundled/core/retry-standards.md +62 -0
  37. package/bundled/core/security-decision.md +65 -0
  38. package/bundled/core/skill-standard-alignment-check.md +79 -0
  39. package/bundled/core/standard-admission-criteria.md +84 -0
  40. package/bundled/core/standard-lifecycle-management.md +94 -0
  41. package/bundled/core/timeout-standards.md +63 -0
  42. package/bundled/core/token-budget.md +58 -0
  43. package/bundled/core/translation-lifecycle-standards.md +162 -0
  44. package/bundled/locales/zh-CN/CHANGELOG.md +51 -3
  45. package/bundled/locales/zh-CN/README.md +1 -1
  46. package/bundled/locales/zh-CN/core/anti-hallucination.md +22 -3
  47. package/bundled/locales/zh-CN/core/anti-sycophancy-prompting.md +192 -0
  48. package/bundled/locales/zh-CN/core/capability-declaration.md +123 -0
  49. package/bundled/locales/zh-CN/core/circuit-breaker.md +106 -0
  50. package/bundled/locales/zh-CN/core/dual-phase-output.md +103 -0
  51. package/bundled/locales/zh-CN/core/failure-source-taxonomy.md +99 -0
  52. package/bundled/locales/zh-CN/core/frontend-design-standards.md +289 -0
  53. package/bundled/locales/zh-CN/core/health-check-standards.md +144 -0
  54. package/bundled/locales/zh-CN/core/immutability-first.md +96 -0
  55. package/bundled/locales/zh-CN/core/packaging-standards.md +224 -0
  56. package/bundled/locales/zh-CN/core/recovery-recipe-registry.md +146 -0
  57. package/bundled/locales/zh-CN/core/retry-standards.md +131 -0
  58. package/bundled/locales/zh-CN/core/security-decision.md +104 -0
  59. package/bundled/locales/zh-CN/core/skill-standard-alignment-check.md +112 -0
  60. package/bundled/locales/zh-CN/core/standard-admission-criteria.md +104 -0
  61. package/bundled/locales/zh-CN/core/standard-lifecycle-management.md +116 -0
  62. package/bundled/locales/zh-CN/core/timeout-standards.md +117 -0
  63. package/bundled/locales/zh-CN/core/token-budget.md +108 -0
  64. package/bundled/locales/zh-CN/core/translation-lifecycle-standards.md +159 -0
  65. package/bundled/locales/zh-TW/CHANGELOG.md +51 -3
  66. package/bundled/locales/zh-TW/README.md +1 -1
  67. package/bundled/locales/zh-TW/core/anti-sycophancy-prompting.md +192 -0
  68. package/bundled/locales/zh-TW/core/capability-declaration.md +111 -0
  69. package/bundled/locales/zh-TW/core/circuit-breaker.md +111 -0
  70. package/bundled/locales/zh-TW/core/dual-phase-output.md +132 -0
  71. package/bundled/locales/zh-TW/core/failure-source-taxonomy.md +146 -0
  72. package/bundled/locales/zh-TW/core/frontend-design-standards.md +460 -0
  73. package/bundled/locales/zh-TW/core/health-check-standards.md +144 -0
  74. package/bundled/locales/zh-TW/core/immutability-first.md +159 -0
  75. package/bundled/locales/zh-TW/core/packaging-standards.md +224 -0
  76. package/bundled/locales/zh-TW/core/recovery-recipe-registry.md +146 -0
  77. package/bundled/locales/zh-TW/core/retry-standards.md +140 -0
  78. package/bundled/locales/zh-TW/core/security-decision.md +120 -0
  79. package/bundled/locales/zh-TW/core/skill-standard-alignment-check.md +112 -0
  80. package/bundled/locales/zh-TW/core/standard-admission-criteria.md +104 -0
  81. package/bundled/locales/zh-TW/core/standard-lifecycle-management.md +116 -0
  82. package/bundled/locales/zh-TW/core/timeout-standards.md +117 -0
  83. package/bundled/locales/zh-TW/core/token-budget.md +143 -0
  84. package/bundled/locales/zh-TW/core/translation-lifecycle-standards.md +159 -0
  85. package/bundled/skills/e2e-assistant/SKILL.md +19 -5
  86. package/bundled/skills/testing-guide/SKILL.md +5 -0
  87. package/bundled/skills/testing-guide/test-skeleton-templates.md +316 -0
  88. package/package.json +2 -1
  89. package/src/commands/check.js +6 -0
  90. package/src/commands/config.js +9 -0
  91. package/src/commands/init.js +97 -46
  92. package/src/commands/mcp.js +26 -0
  93. package/src/commands/run-intent.js +66 -0
  94. package/src/commands/update.js +41 -4
  95. package/src/core/command-router.js +85 -0
  96. package/src/core/project-config.js +91 -0
  97. package/src/flows/init-flow.js +6 -1
  98. package/src/i18n/messages.js +6 -6
  99. package/src/mcp/__tests__/server.test.js +251 -0
  100. package/src/mcp/server.js +352 -0
  101. package/src/prompts/init.js +157 -1
  102. package/src/reconciler/actual-state-scanner.js +24 -0
  103. package/src/uninstallers/hook-uninstaller.js +32 -1
  104. package/src/utils/detect-self-adoption.js +173 -0
  105. package/src/utils/e2e-analyzer.js +88 -5
  106. package/src/utils/e2e-detector.js +73 -1
  107. package/src/utils/integration-generator.js +22 -3
  108. package/standards-registry.json +203 -4
@@ -0,0 +1,159 @@
1
+ ---
2
+ source: ../../../core/immutability-first.md
3
+ source_version: 1.0.0
4
+ translation_version: 1.0.0
5
+ last_synced: 2026-04-20
6
+ status: current
7
+ ---
8
+
9
+ # 不可變性優先架構標準
10
+
11
+ > **語言**: [English](../../../core/immutability-first.md) | 繁體中文
12
+
13
+ **版本**: 1.0.0
14
+ **最後更新**: 2026-04-16
15
+ **適用範圍**: TypeScript 介面、資料流設計、並行系統
16
+ **Scope**: universal
17
+ **來源**: XSPEC-044
18
+
19
+ ---
20
+
21
+ ## 目的
22
+
23
+ 系統級不可變性設計原則:DTO/Value Object 欄位一律 `readonly`,防止並行 Agent 環境下的競態條件。
24
+
25
+ 資料流介面(DTO / Value Object)的欄位一律宣告為 `readonly`,陣列欄位使用 `ReadonlyArray<T>`,物件修改透過展開語法建立新物件,防止並行 Agent 環境下的意外狀態共享與競態條件。
26
+
27
+ ---
28
+
29
+ ## 核心規範
30
+
31
+ - 資料流介面(DTO / Value Object)的所有欄位必須宣告 `readonly`
32
+ - 介面中的陣列型欄位使用 `ReadonlyArray<T>` 而非可變的 `T[]`
33
+ - 修改物件時使用物件展開語法建立新物件,不直接賦值給 `readonly` 欄位
34
+ - 跨並行邊界(`Promise.all` / Worker Thread)傳遞的物件必須為深層不可變
35
+ - 介面中的嵌套物件欄位使用 `Readonly<T>` 包裝(防止淺層保護不足)
36
+
37
+ ---
38
+
39
+ ## 規則詳細說明
40
+
41
+ ### IMM-001:DTO 欄位 readonly(必要)
42
+
43
+ 資料流介面(Data Transfer Objects、Value Objects)的所有欄位必須宣告 `readonly`,防止並行 Agent 環境下的意外狀態共享與競態條件。
44
+
45
+ **錯誤範例**:
46
+ ```typescript
47
+ interface TaskResult {
48
+ status: TaskStatus // ← 可被意外修改
49
+ cost_usd?: number
50
+ }
51
+ ```
52
+
53
+ **正確範例**:
54
+ ```typescript
55
+ interface TaskResult {
56
+ readonly status: TaskStatus // ← 型別安全保護
57
+ readonly cost_usd?: number
58
+ }
59
+ ```
60
+
61
+ ---
62
+
63
+ ### IMM-002:陣列欄位 ReadonlyArray(必要)
64
+
65
+ 介面中的陣列型欄位使用 `ReadonlyArray<T>` 而非可變的 `T[]`,防止 `push`/`splice`/`sort` 等就地修改操作破壞共享陣列。
66
+
67
+ **錯誤範例**:
68
+ ```typescript
69
+ interface MemoryContext {
70
+ recentHistory: IterationRecord[] // ← 可被 push/splice
71
+ }
72
+ ```
73
+
74
+ **正確範例**:
75
+ ```typescript
76
+ interface MemoryContext {
77
+ readonly recentHistory: ReadonlyArray<IterationRecord>
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ### IMM-003:展開語法替代就地修改(必要)
84
+
85
+ 修改物件時使用物件展開語法建立新物件,不直接賦值給 `readonly` 欄位,保留原始物件不變,同時建立可追蹤的修改歷程。
86
+
87
+ **錯誤範例**:
88
+ ```typescript
89
+ options.sessionId = forkId // ← 直接修改,其他持有者看到改變
90
+ ```
91
+
92
+ **正確範例**:
93
+ ```typescript
94
+ const taskOptions = { ...options, sessionId: forkId } // ← 新物件
95
+ ```
96
+
97
+ ---
98
+
99
+ ### IMM-004:並行邊界深層不可變(必要)
100
+
101
+ 跨並行邊界(`Promise.all` / Worker Thread)傳遞的物件必須為深層不可變,並行執行中無法預測存取順序,可變共享物件必然產生競態條件。
102
+
103
+ **正確範例**:
104
+ ```typescript
105
+ // 每個並行任務持有自己的 options 快照
106
+ const batchResults = await Promise.all(
107
+ batch.map(task => {
108
+ const taskOptions = { ...baseOptions, sessionId: forkId }
109
+ return executeOneTask(task, adapter, taskOptions, ...)
110
+ })
111
+ )
112
+ ```
113
+
114
+ ---
115
+
116
+ ### IMM-005:嵌套物件 Readonly 包裝(建議)
117
+
118
+ 介面中的嵌套物件欄位使用 `Readonly<T>` 包裝,頂層 `readonly` 不防止嵌套物件欄位被修改(淺層保護不足)。
119
+
120
+ **錯誤範例**:
121
+ ```typescript
122
+ interface PipelineMemoryEntry {
123
+ readonly metadata: { score?: number } // ← metadata.score 仍可被修改
124
+ }
125
+ ```
126
+
127
+ **正確範例**:
128
+ ```typescript
129
+ interface PipelineMemoryEntry {
130
+ readonly metadata: Readonly<{ score?: number; severity?: string }>
131
+ }
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 適用時機
137
+
138
+ - 設計新的 DTO / Value Object / Config 介面時
139
+ - 跨並行邊界傳遞物件時
140
+ - Agent 間共享狀態設計時
141
+ - Code Review 時檢查介面是否遺漏 `readonly`
142
+
143
+ ---
144
+
145
+ ## 豁免情況
146
+
147
+ - Builder Pattern 的 mutable builder 物件(在 `build()` 後回傳不可變結果)
148
+ - 測試 fixture 的 mutable 建立步驟(建立後視為不可變)
149
+ - 效能關鍵的熱路徑(需有明確的 benchmark 依據才可豁免)
150
+
151
+ ---
152
+
153
+ ## 錯誤碼
154
+
155
+ | 代碼 | 說明 |
156
+ |------|------|
157
+ | `IMM-E001` | `READONLY_VIOLATION` — 嘗試修改 readonly 欄位(TypeScript 編譯期捕獲) |
158
+ | `IMM-E002` | `SHARED_MUTATION` — 跨並行邊界的就地修改導致競態條件 |
159
+ | `IMM-E003` | `SHALLOW_READONLY` — 嵌套物件遺漏 `Readonly<T>` 包裝,淺層保護不足 |
@@ -0,0 +1,224 @@
1
+ ---
2
+ source: ../../../core/packaging-standards.md
3
+ source_version: 1.0.0
4
+ translation_version: 1.0.0
5
+ last_synced: 2026-04-15
6
+ status: current
7
+ ---
8
+
9
+ # 打包標準
10
+
11
+ > **語言**: [English](../../../core/packaging-standards.md) | 繁體中文
12
+
13
+ **版本**: 1.0.0
14
+ **最後更新**: 2026-04-15
15
+ **適用性**: 使用 UDS/DevAP 工具鏈的專案
16
+ **範圍**: 通用 (Universal)
17
+
18
+ ---
19
+
20
+ ## 目的
21
+
22
+ 本標準定義一套基於 Recipe 的打包框架,讓使用者專案可在 `.devap/packaging.yaml` 中宣告打包目標(target)。UDS 負責提供 Recipe 定義與內建 Recipe 函式庫;DevAP 則在 pipeline 中執行編排。
23
+
24
+ 框架的關注點分離如下:
25
+ - **使用者專案**:宣告「打包什麼」(targets + 設定覆蓋)
26
+ - **UDS**:定義「如何打包」(Recipe 結構 + 內建 Recipes)
27
+ - **DevAP**:執行「何時打包」(在 Review 與 Deploy 之間的 pipeline 階段)
28
+
29
+ ---
30
+
31
+ ## 核心原則
32
+
33
+ | 原則 | 說明 |
34
+ |------|------|
35
+ | **Recipe-based** | 每個打包目標都參照一個具名 Recipe;不在 pipeline YAML 中撰寫臨時腳本 |
36
+ | **宣告式 targets** | 專案在 `.devap/packaging.yaml` 中宣告 targets;DevAP 負責解析與執行 |
37
+ | **可客製化** | 四個客製化層允許設定覆蓋、Hook 注入、自訂 Recipe 及 Escape Hatch |
38
+ | **整合至 Pipeline** | 打包作為獨立階段運行於 VibeOps pipeline 的 Review 與 Deploy 之間 |
39
+
40
+ ---
41
+
42
+ ## Recipe 結構
43
+
44
+ Recipe 是定義如何打包專案的 YAML 檔案,欄位定義如下:
45
+
46
+ ```yaml
47
+ # Recipe: <name>.yaml
48
+ name: <string> # 必填 — 唯一識別符(kebab-case)
49
+ description: <string> # 選填 — 人類可讀描述
50
+ requires: # 選填 — 執行前必須存在的檔案
51
+ - <file-path>
52
+ steps: # 必填 — 有序的建置/打包步驟清單
53
+ - run: <shell-command>
54
+ description: <string> # 選填 — 步驟描述
55
+ config: # 選填 — 預設設定值(可被使用者專案覆蓋)
56
+ <key>: <value>
57
+ hooks: # 選填 — 生命週期 hooks(~ 表示不執行)
58
+ preBuild: ~
59
+ postBuild: ~
60
+ prePublish: ~
61
+ postPublish: ~
62
+ ```
63
+
64
+ ### 必填與選填欄位
65
+
66
+ | 欄位 | 必填 | 說明 |
67
+ |------|------|------|
68
+ | `name` | 是 | 唯一識別符,kebab-case 格式 |
69
+ | `steps` | 是 | 至少需要一個步驟 |
70
+ | `description` | 否 | 人類可讀描述 |
71
+ | `requires` | 否 | 前置條件檔案檢查 |
72
+ | `config` | 否 | 預設設定值;所有 key 均可被使用者專案覆蓋 |
73
+ | `hooks` | 否 | 生命週期 hook 插入點;`~` 表示不執行 |
74
+
75
+ ### 步驟變數
76
+
77
+ 設定值與執行時期情境可在 `run` 指令中使用 `{variable}` 占位符:
78
+
79
+ | 變數 | 來源 | 範例 |
80
+ |------|------|------|
81
+ | `{registry}` | `config.registry` | `ghcr.io` |
82
+ | `{name}` | `package.json#name` 或 `config.name` | `my-app` |
83
+ | `{version}` | `package.json#version` 或 `config.version` | `1.2.3` |
84
+ | `{platforms}` | `config.platforms` | `linux/amd64,linux/arm64` |
85
+ | `{output_dir}` | `config.output_dir` | `dist/installers` |
86
+
87
+ ---
88
+
89
+ ## 內建 Recipes
90
+
91
+ UDS 隨附四個內建 Recipe,位於 `recipes/` 目錄:
92
+
93
+ | Recipe | 檔案 | 使用場景 |
94
+ |--------|------|----------|
95
+ | `npm-library` | `recipes/npm-library.yaml` | 不含執行入口的 npm 套件 |
96
+ | `npm-cli` | `recipes/npm-cli.yaml` | 含 `bin` 欄位的 npm 套件(CLI 工具) |
97
+ | `docker-service` | `recipes/docker-service.yaml` | Docker 容器映像建置與推送 |
98
+ | `windows-installer` | `recipes/windows-installer.yaml` | Windows 安裝程式(.msi / .exe)透過使用者腳本 |
99
+
100
+ ### 選擇 Recipe 的決策流程
101
+
102
+ ```
103
+ 產出物是 npm 套件嗎?
104
+ ├── 是 → package.json 是否含有 "bin" 欄位?
105
+ │ ├── 是 → npm-cli
106
+ │ └── 否 → npm-library
107
+ └── 否 → 產出物是容器映像嗎?
108
+ ├── 是 → docker-service
109
+ └── 否 → 產出物是 Windows 安裝程式嗎?
110
+ ├── 是 → windows-installer
111
+ └── 否 → 撰寫自訂 Recipe(參見客製化層)
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 客製化層
117
+
118
+ 需要偏離內建 Recipe 預設值的專案,應使用最低適用層:
119
+
120
+ | 層級 | 機制 | 使用時機 |
121
+ |------|------|----------|
122
+ | **L1 — 設定覆蓋** | `.devap/packaging.yaml` 中的 `config:` 區塊 | 更改預設值(registry URL、tag、輸出目錄)|
123
+ | **L2 — Hook 注入** | `.devap/packaging.yaml` 中的 `hooks:` 區塊 | 在建置或發佈前後執行額外指令 |
124
+ | **L3 — 自訂 Recipe** | 專案 `.devap/recipes/` 中的新 `.yaml` 檔案 | 完全不同的建置流程;內建 Recipe 不適用 |
125
+ | **L4 — Escape Hatch** | target 定義中以 `script:` 取代 `recipe:` | 原始 shell 腳本,無適合的 Recipe 抽象 |
126
+
127
+ ### L1 範例 — 設定覆蓋
128
+
129
+ ```yaml
130
+ # .devap/packaging.yaml
131
+ targets:
132
+ - name: publish-npm
133
+ recipe: npm-library
134
+ config:
135
+ registry: https://npm.pkg.github.com
136
+ access: restricted
137
+ tag: beta
138
+ ```
139
+
140
+ ### L2 範例 — Hook 注入
141
+
142
+ ```yaml
143
+ # .devap/packaging.yaml
144
+ targets:
145
+ - name: docker-push
146
+ recipe: docker-service
147
+ hooks:
148
+ postPush: |
149
+ curl -X POST https://hooks.example.com/deploy-notify \
150
+ -d "{\"version\": \"{version}\"}"
151
+ ```
152
+
153
+ ### L3 範例 — 自訂 Recipe
154
+
155
+ ```yaml
156
+ # .devap/recipes/electron-app.yaml
157
+ name: electron-app
158
+ description: 建置 Electron 桌面應用程式
159
+ requires:
160
+ - package.json
161
+ - electron-builder.yml
162
+ steps:
163
+ - run: npm run build
164
+ - run: npx electron-builder --publish never
165
+ config:
166
+ output_dir: dist
167
+ ```
168
+
169
+ ### L4 範例 — Escape Hatch
170
+
171
+ ```yaml
172
+ # .devap/packaging.yaml
173
+ targets:
174
+ - name: legacy-bundle
175
+ script: |
176
+ ./scripts/legacy-bundle.sh
177
+ mv output/ dist/bundle/
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 打包驗收標準
183
+
184
+ 當以下**所有**條件均滿足時,打包執行視為**成功**:
185
+
186
+ | 標準 | 閾值 | 備註 |
187
+ |------|------|------|
188
+ | 所有 `requires` 檔案存在 | 100% | 在任何步驟執行前檢查 |
189
+ | 所有步驟以 exit code 0 結束 | 100% | 任何非零 exit 使執行失敗 |
190
+ | `postBuild` 產出物存在 | 存在於預期路徑 | 建置步驟後由 DevAP 驗證 |
191
+ | Hook 指令以 exit code 0 結束 | 100% | Hook 失敗會傳播為步驟失敗 |
192
+ | 已發佈產出物可被取回 | HTTP 200 / registry 查詢成功 | 由 DevAP 在發佈後進行 smoke check |
193
+
194
+ ### 失敗處理
195
+
196
+ | 失敗類型 | 行動 | 可重試? |
197
+ |----------|------|----------|
198
+ | `requires` 檔案缺失 | 立即失敗,回報缺失路徑 | 否 |
199
+ | 步驟非零 exit | 立即失敗,若已定義則執行 `postBuild` hook | 可設定(預設:否)|
200
+ | Hook 非零 exit | 立即失敗 | 否 |
201
+ | 發佈無法連線 | 以指數退避重試最多 3 次 | 是(3×)|
202
+
203
+ ---
204
+
205
+ ## 相關標準
206
+
207
+ - [部署標準](deployment-standards.md) — 打包後的部署階段
208
+ - [Pipeline 整合標準](pipeline-integration-standards.md) — CI/CD pipeline 設定
209
+ - [Check-in 標準](checkin-standards.md) — 打包前的品質關卡
210
+ - [版本控制標準](versioning.md) — 套件產出物使用的版本號
211
+
212
+ ---
213
+
214
+ ## 版本歷史
215
+
216
+ | 版本 | 日期 | 變更 |
217
+ |------|------|------|
218
+ | 1.0.0 | 2026-04-15 | 初始發行 — XSPEC-034 Phase 1 |
219
+
220
+ ---
221
+
222
+ ## 授權
223
+
224
+ 本標準以 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 授權發布。
@@ -0,0 +1,146 @@
1
+ ---
2
+ source: ../../../core/recovery-recipe-registry.md
3
+ source_version: 1.0.0
4
+ translation_version: 1.0.0
5
+ last_synced: 2026-04-20
6
+ status: current
7
+ ---
8
+
9
+ # 恢復食譜註冊表標準
10
+
11
+ > **語言**: [English](../../../core/recovery-recipe-registry.md) | 繁體中文
12
+
13
+ **版本**: 1.0.0
14
+ **最後更新**: 2026-04-16
15
+ **適用範圍**: 所有 Agent 執行恢復邏輯
16
+ **Scope**: universal
17
+ **來源**: XSPEC-046(claw-code ROADMAP Phase 3 Recovery Recipes,DEC-035)
18
+ **依賴**: failure-source-taxonomy(XSPEC-045)
19
+
20
+ ---
21
+
22
+ ## 目的
23
+
24
+ 恢復食譜註冊表:將分散的恢復邏輯統一為 YAML 可配置的 Recipe,以 `failureSource` 為匹配鍵。
25
+
26
+ 各模組(Fix Loop、Circuit Breaker、Guardian 自動修復、Staging 重試)的恢復邏輯統一為可外部化的 Recovery Recipe 格式。每個 Recipe 透過 `failureSource`(XSPEC-045)匹配觸發條件,選擇對應的恢復策略,並定義升級路徑(escalation)。無匹配 Recipe 時 fallback 到現有行為(向後相容)。
27
+
28
+ ---
29
+
30
+ ## 核心規範
31
+
32
+ - 每個 Recovery Recipe 必須有唯一 ID(`RR-NNN` 格式)
33
+ - `match.failure_source` 必須是 failure-source-taxonomy 中定義的 8 類之一
34
+ - `escalation.on_exhaust` 必須定義,不得無限循環(如 escalation 指向自身)
35
+ - 無匹配 Recipe 時,系統必須 fallback 到現有預設行為(不得拋出錯誤)
36
+ - 使用者自訂 Recipe 優先於內建 Recipe(同 `failureSource` 時,使用者配置的先匹配)
37
+ - Recipe config 格式錯誤時 fallback 到策略預設值(不中斷執行)
38
+
39
+ ---
40
+
41
+ ## 6 個內建恢復策略
42
+
43
+ ### `fix_loop`
44
+
45
+ - **描述**:注入結構化錯誤回饋,重試任務(現有 Fix Loop)
46
+ - **預設 config**:`max_attempts: 3`, `budget_usd: 0.50`
47
+ - **最適合**:`compilation`, `test_failure`
48
+
49
+ ### `circuit_breaker`
50
+
51
+ - **描述**:三態斷路器保護(XSPEC-036),連續失敗後開路避免雪崩
52
+ - **預設 config**:`failure_threshold: 3`, `cooldown_ms: 30000`
53
+ - **最適合**:`tool_failure`, `prompt_delivery`
54
+
55
+ ### `rebase_and_retry`
56
+
57
+ - **描述**:先執行 git rebase 同步基底分支,再重試任務/迭代
58
+ - **預設 config**:`max_attempts: 1`, `base_branch: "main"`
59
+ - **最適合**:`branch_divergence`
60
+ - **依賴**:XSPEC-047 Branch Drift Detection
61
+
62
+ ### `model_switch`
63
+
64
+ - **描述**:切換至備用模型後重試
65
+ - **預設 config**:`fallback_models: [...]`, `max_attempts: 2`
66
+ - **最適合**:`model_degradation`, `prompt_delivery`
67
+
68
+ ### `degraded_mode`
69
+
70
+ - **描述**:以降級模式繼續執行(如:跳過品質驗證、以部分結果繼續)
71
+ - **結果狀態**:`done_with_concerns`
72
+ - **最適合**:`resource_exhaustion`, `model_degradation`
73
+
74
+ ### `human_checkpoint`
75
+
76
+ - **描述**:暫停執行,等待人工介入(提供失敗細節供判斷)
77
+ - **最適合**:`policy_violation`, `branch_divergence`
78
+ - **備註**:所有其他策略的最終升級路徑
79
+
80
+ ---
81
+
82
+ ## Recipe YAML 格式
83
+
84
+ ```yaml
85
+ id: RR-NNN # 必填,唯一識別符
86
+ name: string # 必填,可讀名稱
87
+ match: # 必填
88
+ failure_source: <FailureSource> # 必填
89
+ severity: [critical, high, ...] # 選填;省略表示匹配所有 severity
90
+ strategy: <RecoveryStrategy> # 必填
91
+ config: {} # 選填;覆蓋策略預設值
92
+ escalation: # 必填
93
+ on_exhaust: <RecoveryStrategy> # 必填;不得指向自身
94
+ message: string # 選填;升級時的通知訊息
95
+ ```
96
+
97
+ ---
98
+
99
+ ## 5 個預設 Recipe
100
+
101
+ | ID | 名稱 | 匹配條件 | 策略 | 升級路徑 |
102
+ |----|------|----------|------|---------|
103
+ | `RR-001` | Fix Loop for Compilation Errors | `compilation` | `fix_loop`(3次, $0.50) | `human_checkpoint` |
104
+ | `RR-002` | Fix Loop for Test Failures | `test_failure` | `fix_loop`(3次, $0.50) | `human_checkpoint` |
105
+ | `RR-003` | Model Switch for Degradation | `model_degradation` | `model_switch`(2次) | `degraded_mode` |
106
+ | `RR-004` | Rebase for Branch Divergence | `branch_divergence` | `rebase_and_retry`(1次) | `human_checkpoint`(需人工解決衝突) |
107
+ | `RR-005` | Degraded Mode for Resource Exhaustion | `resource_exhaustion` | `degraded_mode` | `human_checkpoint` |
108
+
109
+ ---
110
+
111
+ ## 類型定義
112
+
113
+ ### RecoveryStrategy
114
+
115
+ ```
116
+ fix_loop | circuit_breaker | rebase_and_retry | model_switch | degraded_mode | human_checkpoint
117
+ ```
118
+
119
+ ### RecoveryRecipe
120
+
121
+ | 欄位 | 類型 | 必填 |
122
+ |------|------|------|
123
+ | `id` | `string`(RR-NNN 格式) | 是 |
124
+ | `name` | `string` | 是 |
125
+ | `match.failure_source` | `FailureSource` | 是 |
126
+ | `match.severity` | `string[]`(可選) | 否 |
127
+ | `strategy` | `RecoveryStrategy` | 是 |
128
+ | `config` | `object`(可選) | 否 |
129
+ | `escalation.on_exhaust` | `RecoveryStrategy` | 是 |
130
+ | `escalation.message` | `string`(可選) | 否 |
131
+
132
+ ---
133
+
134
+ ## 整合點
135
+
136
+ ### DevAP
137
+
138
+ - `packages/core/src/types.ts` — `RecoveryRecipe` / `RecoveryStrategy` type
139
+ - `packages/core/src/recovery-registry.ts` — Registry 實作與預設 recipe
140
+ - `packages/core/src/orchestrator.ts` — fix loop 前查詢 Registry
141
+
142
+ ### VibeOps
143
+
144
+ - `src/types/index.ts` — 獨立定義 `RecoveryRecipe`(AGPL 隔離)
145
+ - `src/runner/recovery-registry.ts` — 獨立實作
146
+ - `recovery-recipes.yaml` — 預設 recipe 配置
@@ -0,0 +1,140 @@
1
+ ---
2
+ source: ../../../core/retry-standards.md
3
+ source_version: 1.0.0
4
+ translation_version: 1.0.0
5
+ last_synced: 2026-04-20
6
+ status: current
7
+ ---
8
+
9
+ # 重試策略標準
10
+
11
+ > **語言**: [English](../../../core/retry-standards.md) | 繁體中文
12
+
13
+ **版本**: 1.0.0
14
+ **最後更新**: 2026-04-17
15
+ **狀態**: Trial(到期 2026-10-17)
16
+ **適用範圍**: universal
17
+ **來源**: XSPEC-067(DEC-043 Wave 1 可靠性套件)
18
+
19
+ ---
20
+
21
+ ## 目的
22
+
23
+ 重試策略標準:指數退避加抖動、重試上限、依 failure-source 分類的重試規則。
24
+
25
+ 延伸既有 circuit-breaker 與 failure-source-taxonomy,補齊 retry 層的標準化規則。避免各元件各自實作重試造成行為不一致(無上限重試、無 jitter 導致 thundering herd)。
26
+
27
+ ---
28
+
29
+ ## 核心規範
30
+
31
+ - 所有重試邏輯必須使用 exponential + jitter,禁止固定間隔或無 jitter 的純指數
32
+ - 重試必須有明確上限(`max_attempts`),禁止無限重試
33
+ - 重試決策必須先參考 failure-source-taxonomy 分類,fail-fast 類別不得重試
34
+ - 重試必須與 circuit-breaker 整合:OPEN 狀態下不得重試,直接 fail-fast
35
+ - 每次重試都應透過遙測事件上報(`retry_attempted` / `retry_exhausted`)
36
+
37
+ ---
38
+
39
+ ## 退避公式
40
+
41
+ **Exponential with full jitter**:
42
+
43
+ ```
44
+ wait_ms = min(cap_ms, base_ms * 2^attempt) * (0.5 + random() * 0.5)
45
+ ```
46
+
47
+ | 參數 | 預設值 | 說明 |
48
+ |------|--------|------|
49
+ | `base_ms` | `100` | 基底等待時間 |
50
+ | `cap_ms` | `30000` | 等待時間上限 |
51
+ | `max_attempts` | `5` | 最大重試次數 |
52
+ | `jitter_ratio` | `0.5` | ±50% 抖動 |
53
+
54
+ **理由**:
55
+ - Exponential 隨重試次數指數退避,避免短時間大量請求
56
+ - Jitter ±50% 避免 thundering herd(所有 client 同時重試)
57
+ - cap_ms=30s 避免超長等待,與典型 request timeout 對齊
58
+
59
+ ---
60
+
61
+ ## 依 failure-source 的重試規則
62
+
63
+ | 失敗來源 | 可重試 | max_attempts | base_ms | 備註 |
64
+ |---------|--------|-------------|---------|------|
65
+ | `transient_network` | ✅ | 5 | 100 | 短暫網路抖動,指數退避通常可恢復 |
66
+ | `rate_limit` | ✅ | 3 | 1000 | 底數加大預留額度恢復時間;優先採用 Retry-After header |
67
+ | `upstream_unavailable` | ✅ | 3 | 500 | 重試前先查 circuit-breaker |
68
+ | `tool_failure` | ✅ | 2 | 200 | 工具層失敗通常非 transient,僅給 2 次機會 |
69
+ | `prompt_delivery` | ✅ | 2 | 100 | 超過 2 次改走 model_switch |
70
+ | `authentication` | ❌ | — | — | fail-fast;憑證錯誤重試不會變對 |
71
+ | `validation` | ❌ | — | — | fail-fast;input 錯誤重試結果不變 |
72
+ | `policy_violation` | ❌ | — | — | fail-fast;安全決策禁止繞過 |
73
+ | `quota_exhausted` | ❌ | — | — | fail-fast;等 budget reset 或升級 tier |
74
+
75
+ ---
76
+
77
+ ## 與 circuit-breaker 整合
78
+
79
+ | 規則 | 說明 |
80
+ |------|------|
81
+ | Rule 1 | 每次重試前檢查對應 breaker 的 state;若為 OPEN 立即回傳 `CircuitOpenError`,不消耗 `max_attempts` |
82
+ | Rule 2 | 重試全部耗盡(`retry_exhausted`)計入 breaker 的 failure count |
83
+ | Rule 3 | HALF_OPEN 狀態下僅允許 1 次探針重試,不套用 `max_attempts` |
84
+
85
+ ---
86
+
87
+ ## 遙測事件
88
+
89
+ **`retry_attempted`**(每次重試前上傳,第 0 次原始呼叫不算)
90
+
91
+ | 欄位 | 類型 |
92
+ |------|------|
93
+ | `operation` | `string` |
94
+ | `attempt` | `number` |
95
+ | `max_attempts` | `number` |
96
+ | `failure_source` | `FailureSource \| null` |
97
+ | `wait_ms` | `number` |
98
+
99
+ **`retry_exhausted`**(達到 max_attempts 仍失敗時上傳)
100
+
101
+ | 欄位 | 類型 |
102
+ |------|------|
103
+ | `operation` | `string` |
104
+ | `attempts` | `number` |
105
+ | `final_failure_source` | `FailureSource` |
106
+
107
+ ---
108
+
109
+ ## 情境範例
110
+
111
+ **情境 1:指數退避計算**
112
+ - 條件:呼叫下游 API 失敗,failure_source=transient_network,已重試 2 次
113
+ - 第 3 次重試等待時間:`min(30000, 100 * 2^3) * [0.5..1.0] = 400~800ms`
114
+
115
+ **情境 2:authentication fail-fast**
116
+ - 條件:API 回傳 401,failure_source=authentication
117
+ - 結果:立即 fail-fast,不進入退避,不計入 circuit-breaker failure count
118
+
119
+ **情境 3:circuit OPEN 跳過重試**
120
+ - 條件:對應 breaker 為 OPEN,cooldown 剩 15s
121
+ - 結果:立即回傳 CircuitOpenError,不消耗 max_attempts
122
+
123
+ ---
124
+
125
+ ## 錯誤碼
126
+
127
+ | 代碼 | 說明 |
128
+ |------|------|
129
+ | `RETRY-001` | `RETRY_EXHAUSTED` — 達到 max_attempts 仍失敗 |
130
+ | `RETRY-002` | `RETRY_SKIPPED_NON_RETRYABLE` — failure_source 屬 fail-fast 類別 |
131
+ | `RETRY-003` | `RETRY_SKIPPED_CIRCUIT_OPEN` — breaker OPEN 狀態下跳過重試 |
132
+
133
+ ---
134
+
135
+ ## 相關標準
136
+
137
+ - [circuit-breaker.md](circuit-breaker.md) — OPEN 狀態下禁止重試
138
+ - [failure-source-taxonomy.md](failure-source-taxonomy.md) — 依 failureSource 決定 retry/fail-fast
139
+ - [timeout-standards.md](timeout-standards.md) — 單次重試 timeout 不得超過剩餘 deadline
140
+ - [recovery-recipe-registry.md](recovery-recipe-registry.md) — retry 耗盡後交棒給 recovery recipe