universal-dev-standards 5.1.0-beta.7 → 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 (50) hide show
  1. package/README.md +6 -0
  2. package/bin/uds.js +2 -0
  3. package/bundled/ai/standards/translation-lifecycle-standards.ai.yaml +145 -0
  4. package/bundled/core/translation-lifecycle-standards.md +162 -0
  5. package/bundled/locales/zh-CN/CHANGELOG.md +32 -3
  6. package/bundled/locales/zh-CN/README.md +1 -1
  7. package/bundled/locales/zh-CN/core/anti-hallucination.md +22 -3
  8. package/bundled/locales/zh-CN/core/anti-sycophancy-prompting.md +192 -0
  9. package/bundled/locales/zh-CN/core/capability-declaration.md +123 -0
  10. package/bundled/locales/zh-CN/core/circuit-breaker.md +106 -0
  11. package/bundled/locales/zh-CN/core/dual-phase-output.md +103 -0
  12. package/bundled/locales/zh-CN/core/failure-source-taxonomy.md +99 -0
  13. package/bundled/locales/zh-CN/core/frontend-design-standards.md +289 -0
  14. package/bundled/locales/zh-CN/core/health-check-standards.md +144 -0
  15. package/bundled/locales/zh-CN/core/immutability-first.md +96 -0
  16. package/bundled/locales/zh-CN/core/packaging-standards.md +224 -0
  17. package/bundled/locales/zh-CN/core/recovery-recipe-registry.md +146 -0
  18. package/bundled/locales/zh-CN/core/retry-standards.md +131 -0
  19. package/bundled/locales/zh-CN/core/security-decision.md +104 -0
  20. package/bundled/locales/zh-CN/core/skill-standard-alignment-check.md +112 -0
  21. package/bundled/locales/zh-CN/core/standard-admission-criteria.md +104 -0
  22. package/bundled/locales/zh-CN/core/standard-lifecycle-management.md +116 -0
  23. package/bundled/locales/zh-CN/core/timeout-standards.md +117 -0
  24. package/bundled/locales/zh-CN/core/token-budget.md +108 -0
  25. package/bundled/locales/zh-CN/core/translation-lifecycle-standards.md +159 -0
  26. package/bundled/locales/zh-TW/CHANGELOG.md +32 -3
  27. package/bundled/locales/zh-TW/README.md +1 -1
  28. package/bundled/locales/zh-TW/core/anti-sycophancy-prompting.md +8 -0
  29. package/bundled/locales/zh-TW/core/capability-declaration.md +111 -0
  30. package/bundled/locales/zh-TW/core/circuit-breaker.md +111 -0
  31. package/bundled/locales/zh-TW/core/dual-phase-output.md +132 -0
  32. package/bundled/locales/zh-TW/core/failure-source-taxonomy.md +146 -0
  33. package/bundled/locales/zh-TW/core/frontend-design-standards.md +460 -0
  34. package/bundled/locales/zh-TW/core/health-check-standards.md +144 -0
  35. package/bundled/locales/zh-TW/core/immutability-first.md +159 -0
  36. package/bundled/locales/zh-TW/core/recovery-recipe-registry.md +146 -0
  37. package/bundled/locales/zh-TW/core/retry-standards.md +140 -0
  38. package/bundled/locales/zh-TW/core/security-decision.md +120 -0
  39. package/bundled/locales/zh-TW/core/skill-standard-alignment-check.md +112 -0
  40. package/bundled/locales/zh-TW/core/standard-admission-criteria.md +104 -0
  41. package/bundled/locales/zh-TW/core/standard-lifecycle-management.md +116 -0
  42. package/bundled/locales/zh-TW/core/timeout-standards.md +117 -0
  43. package/bundled/locales/zh-TW/core/token-budget.md +143 -0
  44. package/bundled/locales/zh-TW/core/translation-lifecycle-standards.md +159 -0
  45. package/package.json +2 -1
  46. package/src/commands/check.js +6 -0
  47. package/src/commands/init.js +6 -0
  48. package/src/commands/update.js +6 -0
  49. package/src/utils/detect-self-adoption.js +173 -0
  50. package/standards-registry.json +15 -4
@@ -0,0 +1,144 @@
1
+ ---
2
+ source: ../../../core/health-check-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/health-check-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
+ 健康檢查標準:liveness / readiness / startup 三種 probe、深度 health check、結構化 JSON 回應。
24
+
25
+ 業界常見錯誤:把 liveness 和 readiness 混用(健康檢查檢查外部依賴導致連鎖重啟)。本標準明確三種 probe 語意分離,定義深度 health check 的檢查範圍(僅關鍵依賴),並規範結構化 JSON 回應以便下游自動化處理。
26
+
27
+ ---
28
+
29
+ ## 核心規範
30
+
31
+ - Liveness probe 不得檢查外部依賴(DB、下游 API),否則會造成連鎖重啟
32
+ - Readiness probe 可檢查關鍵外部依賴,但僅關鍵(非全部依賴)
33
+ - 慢啟動服務應使用 startup probe,啟動完成後交棒給 liveness
34
+ - Health check 端點必須回傳結構化 JSON,包含 status / dependencies / timestamp
35
+ - Health check 結果應作為 observability 的 Error signal 之一,連續 fail 觸發 incident
36
+
37
+ ---
38
+
39
+ ## 三種 Probe 類型
40
+
41
+ ### Liveness Probe
42
+
43
+ - **目的**:服務是否還活著(process 是否卡死)
44
+ - **建議端點**:`GET /health/live`
45
+ - **允許檢查**:process 是否能回應 HTTP、內部 event loop 是否可用
46
+ - **禁止檢查**:DB 連線、下游 API、消息佇列(會造成連鎖重啟)
47
+ - **失敗行為**:重啟 pod / process
48
+ - **參數**:failureThreshold=3,periodSeconds=10
49
+
50
+ ### Readiness Probe
51
+
52
+ - **目的**:是否可接收流量
53
+ - **建議端點**:`GET /health/ready`
54
+ - **允許檢查**:自身 API 可用、DB 連線(若服務必須依賴 DB)、關鍵下游依賴、必要設定已載入
55
+ - **禁止檢查**:非關鍵依賴(避免非關鍵故障造成服務被移出負載均衡)
56
+ - **失敗行為**:移出負載均衡,不重啟
57
+ - **參數**:failureThreshold=3,periodSeconds=5
58
+
59
+ ### Startup Probe
60
+
61
+ - **目的**:啟動期專用,替代慢啟動服務的 liveness
62
+ - **建議端點**:`GET /health/startup`
63
+ - **檢查項目**:啟動過程所需資源(如快取預熱、index 載入)已完成
64
+ - **失敗行為**:重啟 pod(啟動超時)
65
+ - **完成後**:停用,改由 liveness 接手
66
+ - **參數**:failureThreshold=30,periodSeconds=10
67
+
68
+ ---
69
+
70
+ ## 深度規則
71
+
72
+ | 層級 | 使用時機 | 檢查範圍 |
73
+ |------|---------|---------|
74
+ | Shallow | Liveness | process 是否可回應,不碰任何外部依賴 |
75
+ | Deep | Readiness | 自身 API 路由、DB ping(若必須)、關鍵下游 API ping |
76
+
77
+ **關鍵依賴的定義**:沒有它服務就完全無法提供核心功能。
78
+
79
+ ---
80
+
81
+ ## 回應格式
82
+
83
+ **Content-Type**:`application/json`
84
+
85
+ | HTTP 狀態碼 | 意義 |
86
+ |------------|------|
87
+ | `200` | healthy — 所有關鍵依賴正常 |
88
+ | `503` | unhealthy — 至少一個關鍵依賴失敗 |
89
+
90
+ **JSON Schema**:
91
+
92
+ ```json
93
+ {
94
+ "status": "healthy | degraded | unhealthy",
95
+ "timestamp": "<ISO-8601>",
96
+ "uptime_seconds": 12345,
97
+ "version": "1.0.0",
98
+ "dependencies": {
99
+ "database": {
100
+ "status": "healthy | unhealthy",
101
+ "latency_ms": 5,
102
+ "last_check": "<ISO-8601>"
103
+ },
104
+ "upstream_api": {
105
+ "status": "healthy | unhealthy",
106
+ "latency_ms": 20
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ## 與 Observability 整合
115
+
116
+ - Health check 結果應作為 RED metric 的 Error 來源之一(Rate / Errors / Duration)
117
+ - 連續 N 次 health check failed 應觸發 incident(對齊 incident-response)
118
+ - probe 延遲本身應被監控(異常緩慢可能是 resource_exhaustion 徵兆)
119
+
120
+ ---
121
+
122
+ ## 情境範例
123
+
124
+ **情境 1:liveness 不檢查 DB**
125
+ - 條件:DB 暫時無法連線
126
+ - Liveness 回傳 200 healthy(不檢查 DB),避免連鎖重啟
127
+
128
+ **情境 2:readiness 因關鍵依賴失敗**
129
+ - 條件:關鍵下游 API 不可達
130
+ - Readiness 回傳 503,pod 移出負載均衡但不重啟
131
+
132
+ **情境 3:startup 後交棒 liveness**
133
+ - 條件:服務需 60s 預熱快取
134
+ - 前 60s startup probe 持續回 503,預熱完成後交棒 liveness
135
+
136
+ ---
137
+
138
+ ## 錯誤碼
139
+
140
+ | 代碼 | 說明 |
141
+ |------|------|
142
+ | `HC-001` | `HEALTH_CHECK_FAILED` — 關鍵依賴失敗 |
143
+ | `HC-002` | `HEALTH_CHECK_TIMEOUT` — probe 本身超時 |
144
+ | `HC-003` | `INVALID_DEPENDENCY_SET` — readiness 檢查了非關鍵依賴(設計違規) |
@@ -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,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
@@ -0,0 +1,120 @@
1
+ ---
2
+ source: ../../../core/security-decision.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/security-decision.md) | 繁體中文
12
+
13
+ **版本**: 1.0.0
14
+ **最後更新**: 2026-04-15
15
+ **適用範圍**: 所有多來源安全決策仲裁場景
16
+ **Scope**: universal
17
+ **來源**: XSPEC-037(claude-code-book Ch.4 deny>ask>allow pipeline)
18
+
19
+ ---
20
+
21
+ ## 目的
22
+
23
+ 安全決策鐵律:`deny > ask > allow` 三態優先級仲裁。
24
+
25
+ 多來源安全決策的仲裁規則:`deny` 永遠勝出,無論來源優先級。三態語義(deny / ask / allow)比布林值更精確,支援「需使用者確認」的中間狀態。
26
+
27
+ ---
28
+
29
+ ## 核心規範
30
+
31
+ - 所有安全決策仲裁必須遵循 `deny > ask > allow` 優先級,無例外
32
+ - `deny` 的勝出不受規則來源優先級影響(低優先級的 deny 可以覆蓋高優先級的 allow)
33
+ - `ask` 狀態在 CI / 無人值守模式下必須等同 `deny`(無法互動確認)
34
+ - 決策結果必須記錄來源規則列表(可追蹤性)
35
+ - `projectSettings` 來源的安全提升操作必須被拒絕(信任半徑保護)
36
+
37
+ ---
38
+
39
+ ## 三態決策類型
40
+
41
+ | 決策 | 優先級 | 描述 |
42
+ |------|--------|------|
43
+ | `deny` | 1(最高) | 明確拒絕,立即阻止操作。任何來源的 deny 都使最終決策為 deny |
44
+ | `ask` | 2 | 需要使用者確認才能繼續。CI 模式下等同 deny(無法互動) |
45
+ | `allow` | 3(最低) | 允許操作繼續。所有規則都為 allow 時才能執行 |
46
+
47
+ ---
48
+
49
+ ## 仲裁規則
50
+
51
+ ```typescript
52
+ function arbitrate(rules: SecurityDecisionRule[]): SecurityDecision {
53
+ if (rules.some(r => r.decision === "deny")) return "deny";
54
+ if (rules.some(r => r.decision === "ask")) return "ask";
55
+ return "allow";
56
+ }
57
+ ```
58
+
59
+ **不變式**:`deny` 勝出不受 `source` 優先級影響。
60
+
61
+ ---
62
+
63
+ ## 介面定義
64
+
65
+ ### SecurityDecision
66
+
67
+ ```
68
+ deny | ask | allow
69
+ ```
70
+
71
+ ### SecurityDecisionRule
72
+
73
+ | 欄位 | 類型 | 說明 |
74
+ |------|------|------|
75
+ | `source` | `string` | 規則來源(user / project / policy / builtin) |
76
+ | `decision` | `SecurityDecision` | 決策值 |
77
+ | `reason` | `string`(可選) | 用於日誌和使用者說明 |
78
+
79
+ ### SecurityDecisionResult
80
+
81
+ | 欄位 | 類型 | 說明 |
82
+ |------|------|------|
83
+ | `final_decision` | `SecurityDecision` | 最終決策 |
84
+ | `winning_rules` | `SecurityDecisionRule[]` | 觸發最終決策的規則 |
85
+ | `all_rules` | `SecurityDecisionRule[]` | 所有評估的規則(審計用) |
86
+ | `ci_mode_override` | `boolean` | `true` 時 ask → deny |
87
+
88
+ ---
89
+
90
+ ## 信任半徑保護
91
+
92
+ `projectSettings` 在安全敏感操作中被排除(防止惡意 repo 注入)。
93
+
94
+ **被阻擋的操作**:
95
+
96
+ - 將 `requiresUserConfirmation` 設為 `false`
97
+ - 記憶體路徑重定向到專案目錄外(如 `~/.ssh`)
98
+ - 工具白名單擴充超出 `userSettings` 允許的範圍
99
+ - 安全規則降級(deny → allow)
100
+
101
+ 拒絕時記錄 `warn` 等級日誌:`[WARN] projectSettings security override rejected: {operation}`
102
+
103
+ ---
104
+
105
+ ## 適用組件
106
+
107
+ - DevAP Safety Hook
108
+ - VibeOps CommandPolicy
109
+ - VibeOps Governance Framework(SPEC-049)
110
+ - 任何多來源規則合併的安全仲裁場景
111
+
112
+ ---
113
+
114
+ ## 錯誤碼
115
+
116
+ | 代碼 | 說明 |
117
+ |------|------|
118
+ | `SD-001` | `SECURITY_DENIED` — deny 決策,操作被阻止 |
119
+ | `SD-002` | `SECURITY_ASK_CI` — ask 在 CI 模式下被視為 deny |
120
+ | `SD-003` | `TRUST_RADIUS_VIOLATION` — projectSettings 嘗試安全提升,已拒絕 |