universal-dev-standards 5.1.0-beta.5 → 5.1.0-beta.7
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.
- package/bin/uds.js +41 -5
- package/bundled/ai/standards/agent-communication-protocol.ai.yaml +34 -0
- package/bundled/ai/standards/anti-hallucination.ai.yaml +49 -2
- package/bundled/ai/standards/anti-sycophancy-prompting.ai.yaml +111 -0
- package/bundled/ai/standards/capability-declaration.ai.yaml +113 -0
- package/bundled/ai/standards/circuit-breaker.ai.yaml +93 -0
- package/bundled/ai/standards/developer-memory.ai.yaml +13 -0
- package/bundled/ai/standards/dual-phase-output.ai.yaml +108 -0
- package/bundled/ai/standards/execution-history.ai.yaml +3 -2
- package/bundled/ai/standards/failure-source-taxonomy.ai.yaml +115 -0
- package/bundled/ai/standards/frontend-design-standards.ai.yaml +305 -0
- package/bundled/ai/standards/health-check-standards.ai.yaml +140 -0
- package/bundled/ai/standards/immutability-first.ai.yaml +112 -0
- package/bundled/ai/standards/model-selection.ai.yaml +111 -3
- package/bundled/ai/standards/packaging-standards.ai.yaml +142 -0
- package/bundled/ai/standards/recovery-recipe-registry.ai.yaml +200 -0
- package/bundled/ai/standards/retry-standards.ai.yaml +134 -0
- package/bundled/ai/standards/security-decision.ai.yaml +87 -0
- package/bundled/ai/standards/skill-standard-alignment-check.ai.yaml +119 -0
- package/bundled/ai/standards/standard-admission-criteria.ai.yaml +107 -0
- package/bundled/ai/standards/standard-lifecycle-management.ai.yaml +144 -0
- package/bundled/ai/standards/timeout-standards.ai.yaml +104 -0
- package/bundled/ai/standards/token-budget.ai.yaml +108 -0
- package/bundled/core/anti-hallucination.md +21 -2
- package/bundled/core/anti-sycophancy-prompting.md +184 -0
- package/bundled/core/capability-declaration.md +59 -0
- package/bundled/core/circuit-breaker.md +58 -0
- package/bundled/core/developer-memory.md +29 -1
- package/bundled/core/dual-phase-output.md +56 -0
- package/bundled/core/failure-source-taxonomy.md +72 -0
- package/bundled/core/frontend-design-standards.md +474 -0
- package/bundled/core/health-check-standards.md +72 -0
- package/bundled/core/immutability-first.md +105 -0
- package/bundled/core/model-selection.md +80 -0
- package/bundled/core/packaging-standards.md +216 -0
- package/bundled/core/recovery-recipe-registry.md +69 -0
- package/bundled/core/retry-standards.md +62 -0
- package/bundled/core/security-decision.md +65 -0
- package/bundled/core/skill-standard-alignment-check.md +79 -0
- package/bundled/core/standard-admission-criteria.md +84 -0
- package/bundled/core/standard-lifecycle-management.md +94 -0
- package/bundled/core/timeout-standards.md +63 -0
- package/bundled/core/token-budget.md +58 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +40 -3
- package/bundled/locales/zh-CN/README.md +4 -4
- package/bundled/locales/zh-CN/SECURITY.md +1 -0
- package/bundled/locales/zh-TW/CHANGELOG.md +40 -3
- package/bundled/locales/zh-TW/README.md +4 -4
- package/bundled/locales/zh-TW/SECURITY.md +1 -0
- package/bundled/locales/zh-TW/ai/standards/anti-hallucination.ai.yaml +49 -2
- package/bundled/locales/zh-TW/core/anti-sycophancy-prompting.md +184 -0
- package/bundled/locales/zh-TW/core/packaging-standards.md +224 -0
- package/bundled/skills/e2e-assistant/SKILL.md +19 -5
- package/bundled/skills/testing-guide/SKILL.md +5 -0
- package/bundled/skills/testing-guide/test-skeleton-templates.md +316 -0
- package/package.json +1 -1
- package/src/commands/config.js +26 -2
- package/src/commands/init.js +91 -46
- package/src/commands/mcp.js +26 -0
- package/src/commands/run-intent.js +66 -0
- package/src/commands/update.js +50 -4
- package/src/core/command-router.js +85 -0
- package/src/core/project-config.js +91 -0
- package/src/flows/init-flow.js +6 -1
- package/src/i18n/messages.js +6 -6
- package/src/installers/manifest-installer.js +1 -1
- package/src/mcp/__tests__/server.test.js +251 -0
- package/src/mcp/server.js +352 -0
- package/src/prompts/init.js +157 -1
- package/src/reconciler/actual-state-scanner.js +24 -0
- package/src/uninstallers/hook-uninstaller.js +32 -1
- package/src/utils/e2e-analyzer.js +88 -5
- package/src/utils/e2e-detector.js +73 -1
- package/src/utils/integration-generator.js +22 -3
- package/standards-registry.json +193 -5
|
@@ -8,10 +8,10 @@ standard:
|
|
|
8
8
|
description: AI 模型分級選擇策略
|
|
9
9
|
|
|
10
10
|
meta:
|
|
11
|
-
version: "
|
|
12
|
-
updated: "2026-
|
|
11
|
+
version: "2.0.0"
|
|
12
|
+
updated: "2026-04-13"
|
|
13
13
|
source: core/model-selection.md
|
|
14
|
-
description:
|
|
14
|
+
description: "三層模型分級選擇策略 + 多模型池能力管理(XSPEC-027)"
|
|
15
15
|
inspired_by: superpowers/subagent-driven-development
|
|
16
16
|
|
|
17
17
|
guidelines:
|
|
@@ -70,6 +70,112 @@ standard:
|
|
|
70
70
|
action: "從 standard 或更高層級開始"
|
|
71
71
|
priority: medium
|
|
72
72
|
|
|
73
|
+
capability_dimensions:
|
|
74
|
+
description: "能力維度分類與評分說明(XSPEC-027, DEC-031, DEC-032)"
|
|
75
|
+
scoring_scale:
|
|
76
|
+
5: "生產就緒 — 高準確率,可直接使用"
|
|
77
|
+
4: "良好 — 偶有遺漏,可接受"
|
|
78
|
+
3: "基本可用 — 需人工補充"
|
|
79
|
+
2: "部分可用 — 僅供參考"
|
|
80
|
+
1: "不可靠 — 不建議使用"
|
|
81
|
+
dimensions:
|
|
82
|
+
modality:
|
|
83
|
+
vision:
|
|
84
|
+
description: "圖片/截圖理解能力(UI 分析、圖表解讀)"
|
|
85
|
+
benchmark: "internal-vision-bench"
|
|
86
|
+
scoring_guide:
|
|
87
|
+
5: "≥ 90% 準確,可萃取完整 DESIGN.md"
|
|
88
|
+
4: "75-89%,偶有遺漏但可用"
|
|
89
|
+
3: "60-74%,需人工補充"
|
|
90
|
+
2: "40-59%,僅供參考"
|
|
91
|
+
1: "< 40%,不可靠"
|
|
92
|
+
audio:
|
|
93
|
+
description: "語音理解能力"
|
|
94
|
+
benchmark: "future-audio-bench"
|
|
95
|
+
image_generation:
|
|
96
|
+
description: "圖片生成能力"
|
|
97
|
+
benchmark: "provider-specific"
|
|
98
|
+
reasoning:
|
|
99
|
+
code_reasoning:
|
|
100
|
+
description: "程式碼理解與生成品質"
|
|
101
|
+
benchmark: "humaneval-plus"
|
|
102
|
+
math_reasoning:
|
|
103
|
+
description: "數學推理準確率"
|
|
104
|
+
benchmark: "gsm8k"
|
|
105
|
+
instruction_following:
|
|
106
|
+
description: "複雜多步驟指令遵循率(VibeOps 最重視)"
|
|
107
|
+
benchmark: "internal-instruction-bench"
|
|
108
|
+
long_context_quality:
|
|
109
|
+
description: "長文件中間段資訊存取(Lost-in-the-Middle)"
|
|
110
|
+
benchmark: "needle-in-haystack"
|
|
111
|
+
output:
|
|
112
|
+
structured_output:
|
|
113
|
+
description: "JSON mode / Schema 格式輸出成功率"
|
|
114
|
+
benchmark: "internal-json-bench"
|
|
115
|
+
tool_use:
|
|
116
|
+
description: "Function Calling 正確率"
|
|
117
|
+
benchmark: "internal-tool-bench"
|
|
118
|
+
language:
|
|
119
|
+
multilingual_zh_tw:
|
|
120
|
+
description: "繁體中文品質(本系統優先語言)"
|
|
121
|
+
benchmark: "internal-zh-tw-bench"
|
|
122
|
+
|
|
123
|
+
capability_registry:
|
|
124
|
+
description: "模型能力登記表(DEC-031 D1)。各子專案依實際測試維護分數。"
|
|
125
|
+
format:
|
|
126
|
+
model_id: "provider/model-name"
|
|
127
|
+
version_pinned: "版本鎖定識別(SHA、日期戳或 model_version)"
|
|
128
|
+
pin_date: "鎖定日期(YYYY-MM-DD)"
|
|
129
|
+
eol_date: "預期淘汰日期(可選,YYYY-MM-DD)"
|
|
130
|
+
capabilities:
|
|
131
|
+
"<dimension>.<subdimension>": "<1-5 整數分>"
|
|
132
|
+
examples:
|
|
133
|
+
- model_id: "anthropic/claude-sonnet-4-6"
|
|
134
|
+
version_pinned: "claude-sonnet-4-6"
|
|
135
|
+
pin_date: "2026-04-13"
|
|
136
|
+
capabilities:
|
|
137
|
+
"modality.vision": 4
|
|
138
|
+
"reasoning.instruction_following": 5
|
|
139
|
+
"reasoning.code_reasoning": 5
|
|
140
|
+
"output.structured_output": 5
|
|
141
|
+
"output.tool_use": 5
|
|
142
|
+
"language.multilingual_zh_tw": 5
|
|
143
|
+
- model_id: "anthropic/claude-haiku-4-5"
|
|
144
|
+
version_pinned: "claude-haiku-4-5-20251001"
|
|
145
|
+
pin_date: "2026-04-13"
|
|
146
|
+
capabilities:
|
|
147
|
+
"modality.vision": 3
|
|
148
|
+
"reasoning.instruction_following": 4
|
|
149
|
+
"reasoning.code_reasoning": 4
|
|
150
|
+
"output.structured_output": 4
|
|
151
|
+
"output.tool_use": 4
|
|
152
|
+
"language.multilingual_zh_tw": 4
|
|
153
|
+
|
|
154
|
+
routing_rules:
|
|
155
|
+
description: "能力路由決策規則(DEC-031 D2, DEC-032 D3)"
|
|
156
|
+
selection_strategy: "pareto_weighted"
|
|
157
|
+
rules:
|
|
158
|
+
- id: CAP-001
|
|
159
|
+
condition: "任務需要 capability X,模型得分 ≥ min_score"
|
|
160
|
+
action: "SUPPORTED — 正常執行"
|
|
161
|
+
priority: high
|
|
162
|
+
- id: CAP-002
|
|
163
|
+
condition: "任務需要 capability X,模型得分 2-3(min_score 未達但 ≥ 2)"
|
|
164
|
+
action: "DEGRADED — 降級流程執行,產出標記 [DEGRADED]"
|
|
165
|
+
priority: medium
|
|
166
|
+
- id: CAP-003
|
|
167
|
+
condition: "任務需要 capability X,模型得分 ≤ 1 或未登記"
|
|
168
|
+
action: "UNSUPPORTED — 使用替代流程或提示用戶"
|
|
169
|
+
priority: high
|
|
170
|
+
- id: CAP-004
|
|
171
|
+
condition: "模型降智偵測(DEC-033)觸發 moderate 信號"
|
|
172
|
+
action: "啟動金絲雀測試,同時記錄降智警告"
|
|
173
|
+
priority: high
|
|
174
|
+
- id: CAP-005
|
|
175
|
+
condition: "模型降智偵測觸發 critical 信號"
|
|
176
|
+
action: "自動切換備用模型,上報 P1 Issue"
|
|
177
|
+
priority: critical
|
|
178
|
+
|
|
73
179
|
physical_spec:
|
|
74
180
|
type: checklist
|
|
75
181
|
validator:
|
|
@@ -79,3 +185,5 @@ physical_spec:
|
|
|
79
185
|
- "是否根據複雜度信號選擇模型等級"
|
|
80
186
|
- "BLOCKED 時是否嘗試升級而非直接失敗"
|
|
81
187
|
- "簡單任務是否避免使用過高等級模型"
|
|
188
|
+
- "能力登記表是否包含 version_pinned 與 pin_date"
|
|
189
|
+
- "路由決策是否依 SUPPORTED/DEGRADED/UNSUPPORTED 三態處理"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Packaging Standards (AI-Optimized v1)
|
|
2
|
+
# Source: core/packaging-standards.md
|
|
3
|
+
|
|
4
|
+
standard:
|
|
5
|
+
id: packaging
|
|
6
|
+
name: Packaging Standards
|
|
7
|
+
description: Recipe-based packaging framework for user projects using UDS/DevAP toolchain
|
|
8
|
+
guidelines:
|
|
9
|
+
- "Recipe-based: use built-in or custom recipes for each packaging target"
|
|
10
|
+
- "Declarative: declare targets in .devap/packaging.yaml"
|
|
11
|
+
- "Customizable: override config, inject hooks, or write custom recipes"
|
|
12
|
+
- "Pipeline-integrated: packaging runs between Review and Deploy in VibeOps"
|
|
13
|
+
|
|
14
|
+
meta:
|
|
15
|
+
version: "1.0.0"
|
|
16
|
+
updated: "2026-04-15"
|
|
17
|
+
source: core/packaging-standards.md
|
|
18
|
+
|
|
19
|
+
principles:
|
|
20
|
+
core:
|
|
21
|
+
- recipe_based: "Every packaging target references a named Recipe; no ad-hoc scripts in pipeline YAML"
|
|
22
|
+
- declarative_targets: "Projects declare targets in .devap/packaging.yaml; DevAP resolves and executes"
|
|
23
|
+
- customizable: "Four customization layers allow config overrides, hook injection, custom Recipes, and escape hatches"
|
|
24
|
+
- pipeline_integrated: "Packaging runs as a named stage between Review and Deploy"
|
|
25
|
+
|
|
26
|
+
recipe_structure:
|
|
27
|
+
required_fields: [name, steps]
|
|
28
|
+
optional_fields: [description, requires, config, hooks]
|
|
29
|
+
step_fields:
|
|
30
|
+
required: [run]
|
|
31
|
+
optional: [description]
|
|
32
|
+
hook_points: [preBuild, postBuild, prePublish, postPublish]
|
|
33
|
+
config_variables:
|
|
34
|
+
- name: "{registry}"
|
|
35
|
+
source: "config.registry"
|
|
36
|
+
- name: "{name}"
|
|
37
|
+
source: "package.json#name or config.name"
|
|
38
|
+
- name: "{version}"
|
|
39
|
+
source: "package.json#version or config.version"
|
|
40
|
+
- name: "{platforms}"
|
|
41
|
+
source: "config.platforms"
|
|
42
|
+
- name: "{output_dir}"
|
|
43
|
+
source: "config.output_dir"
|
|
44
|
+
|
|
45
|
+
built_in_recipes:
|
|
46
|
+
npm_library:
|
|
47
|
+
file: recipes/npm-library.yaml
|
|
48
|
+
use_case: "npm package without a binary entry point"
|
|
49
|
+
requires: [package.json, tsconfig.json]
|
|
50
|
+
steps: [npm run build, npm pack, npm publish]
|
|
51
|
+
default_config:
|
|
52
|
+
registry: https://registry.npmjs.org
|
|
53
|
+
access: public
|
|
54
|
+
tag: latest
|
|
55
|
+
npm_cli:
|
|
56
|
+
file: recipes/npm-cli.yaml
|
|
57
|
+
use_case: "npm package with bin field (CLI tool)"
|
|
58
|
+
requires: [package.json, tsconfig.json]
|
|
59
|
+
steps: [npm run build, verify_bin_field, npm pack, npm publish]
|
|
60
|
+
default_config:
|
|
61
|
+
registry: https://registry.npmjs.org
|
|
62
|
+
access: public
|
|
63
|
+
tag: latest
|
|
64
|
+
docker_service:
|
|
65
|
+
file: recipes/docker-service.yaml
|
|
66
|
+
use_case: "Docker container image build and push"
|
|
67
|
+
requires: [Dockerfile]
|
|
68
|
+
steps: [docker buildx build, docker push, docker tag latest, docker push latest]
|
|
69
|
+
default_config:
|
|
70
|
+
registry: ghcr.io
|
|
71
|
+
platforms: linux/amd64,linux/arm64
|
|
72
|
+
push_latest: true
|
|
73
|
+
windows_installer:
|
|
74
|
+
file: recipes/windows-installer.yaml
|
|
75
|
+
use_case: "Windows installer (.msi or .exe) via user-provided build script"
|
|
76
|
+
requires: [package.json, "packaging/windows-build.sh"]
|
|
77
|
+
steps: [npm run build, bash packaging/windows-build.sh]
|
|
78
|
+
default_config:
|
|
79
|
+
output_dir: dist/installers
|
|
80
|
+
format: msi
|
|
81
|
+
|
|
82
|
+
customization_layers:
|
|
83
|
+
L1:
|
|
84
|
+
name: config_override
|
|
85
|
+
mechanism: "config: block in .devap/packaging.yaml"
|
|
86
|
+
when: "Change default values (registry URL, tag, output dir)"
|
|
87
|
+
L2:
|
|
88
|
+
name: hook_injection
|
|
89
|
+
mechanism: "hooks: block in .devap/packaging.yaml"
|
|
90
|
+
when: "Run extra commands before/after build or publish"
|
|
91
|
+
L3:
|
|
92
|
+
name: custom_recipe
|
|
93
|
+
mechanism: "New .yaml file in project's .devap/recipes/"
|
|
94
|
+
when: "Entirely different build process; built-ins don't apply"
|
|
95
|
+
L4:
|
|
96
|
+
name: escape_hatch
|
|
97
|
+
mechanism: "script: key replacing recipe: in target definition"
|
|
98
|
+
when: "Raw shell script when no Recipe abstraction is suitable"
|
|
99
|
+
|
|
100
|
+
acceptance_criteria:
|
|
101
|
+
success_conditions:
|
|
102
|
+
- condition: "All requires files exist"
|
|
103
|
+
threshold: "100%"
|
|
104
|
+
timing: "Before any step runs"
|
|
105
|
+
- condition: "All steps exit with code 0"
|
|
106
|
+
threshold: "100%"
|
|
107
|
+
timing: "Per step"
|
|
108
|
+
- condition: "postBuild artifact exists"
|
|
109
|
+
threshold: "Present in expected path"
|
|
110
|
+
timing: "After build step"
|
|
111
|
+
- condition: "Hook commands exit with code 0"
|
|
112
|
+
threshold: "100%"
|
|
113
|
+
timing: "Per hook"
|
|
114
|
+
- condition: "Published artifact is retrievable"
|
|
115
|
+
threshold: "HTTP 200 / registry query succeeds"
|
|
116
|
+
timing: "Post-publish smoke check"
|
|
117
|
+
failure_handling:
|
|
118
|
+
missing_requires: {action: "fail immediately", retry: false}
|
|
119
|
+
step_nonzero_exit: {action: "fail immediately, run postBuild hook if defined", retry: "configurable"}
|
|
120
|
+
hook_nonzero_exit: {action: "fail immediately", retry: false}
|
|
121
|
+
publish_unreachable: {action: "retry with exponential backoff", retry: true, max_retries: 3}
|
|
122
|
+
|
|
123
|
+
recipe_selection_guide:
|
|
124
|
+
decision_tree:
|
|
125
|
+
is_npm_package:
|
|
126
|
+
yes:
|
|
127
|
+
has_bin_field:
|
|
128
|
+
yes: npm-cli
|
|
129
|
+
no: npm-library
|
|
130
|
+
no:
|
|
131
|
+
is_container_image:
|
|
132
|
+
yes: docker-service
|
|
133
|
+
no:
|
|
134
|
+
is_windows_installer:
|
|
135
|
+
yes: windows-installer
|
|
136
|
+
no: custom-recipe-required
|
|
137
|
+
|
|
138
|
+
physical_spec:
|
|
139
|
+
type: custom_script
|
|
140
|
+
validator:
|
|
141
|
+
command: "test -f .devap/packaging.yaml"
|
|
142
|
+
rule: "packaging_config_declared"
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Recovery Recipe Registry Standard - AI Optimized
|
|
2
|
+
# Source: XSPEC-046 (claw-code ROADMAP Phase 3 Recovery Recipes, DEC-035)
|
|
3
|
+
|
|
4
|
+
standard:
|
|
5
|
+
id: recovery-recipe-registry
|
|
6
|
+
name: Recovery Recipe Registry Standard
|
|
7
|
+
description: 恢復食譜註冊表 — 將分散的恢復邏輯統一為 YAML 可配置的 Recipe,以 failureSource 為匹配鍵
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
version: "1.0.0"
|
|
11
|
+
updated: "2026-04-16"
|
|
12
|
+
source: XSPEC-046
|
|
13
|
+
description: >
|
|
14
|
+
各模組(Fix Loop、Circuit Breaker、Guardian 自動修復、Staging 重試)的恢復邏輯
|
|
15
|
+
統一為可外部化的 Recovery Recipe 格式。每個 Recipe 透過 failureSource(XSPEC-045)
|
|
16
|
+
匹配觸發條件,選擇對應的恢復策略,並定義升級路徑(escalation)。
|
|
17
|
+
無匹配 Recipe 時 fallback 到現有行為(向後相容)。
|
|
18
|
+
scope: universal
|
|
19
|
+
borrowed_from: "ultraworkers/claw-code ROADMAP Phase 3 Recovery Recipes (adapted to YAML format)"
|
|
20
|
+
depends_on: "failure-source-taxonomy.ai.yaml (XSPEC-045)"
|
|
21
|
+
|
|
22
|
+
guidelines:
|
|
23
|
+
- "每個 Recovery Recipe 必須有唯一 ID(RR-NNN 格式)"
|
|
24
|
+
- "match.failure_source 必須是 failure-source-taxonomy 中定義的 8 類之一"
|
|
25
|
+
- "escalation.on_exhaust 必須定義,不得無限循環(如 escalation 指向自身)"
|
|
26
|
+
- "無匹配 Recipe 時,系統必須 fallback 到現有預設行為(不得拋出錯誤)"
|
|
27
|
+
- "使用者自訂 Recipe 優先於內建 Recipe(同 failureSource 時,使用者配置的先匹配)"
|
|
28
|
+
- "Recipe config 格式錯誤時 fallback 到策略預設值(不中斷執行)"
|
|
29
|
+
|
|
30
|
+
strategies:
|
|
31
|
+
fix_loop:
|
|
32
|
+
description: "注入結構化錯誤回饋,重試任務(現有 Fix Loop)"
|
|
33
|
+
config:
|
|
34
|
+
max_attempts:
|
|
35
|
+
type: number
|
|
36
|
+
default: 3
|
|
37
|
+
budget_usd:
|
|
38
|
+
type: number
|
|
39
|
+
default: 0.50
|
|
40
|
+
best_for: [compilation, test_failure]
|
|
41
|
+
|
|
42
|
+
circuit_breaker:
|
|
43
|
+
description: "三態斷路器保護(XSPEC-036),連續失敗後開路避免雪崩"
|
|
44
|
+
config:
|
|
45
|
+
failure_threshold:
|
|
46
|
+
type: number
|
|
47
|
+
default: 3
|
|
48
|
+
cooldown_ms:
|
|
49
|
+
type: number
|
|
50
|
+
default: 30000
|
|
51
|
+
best_for: [tool_failure, prompt_delivery]
|
|
52
|
+
|
|
53
|
+
rebase_and_retry:
|
|
54
|
+
description: "先執行 git rebase 同步基底分支,再重試任務/迭代"
|
|
55
|
+
config:
|
|
56
|
+
max_attempts:
|
|
57
|
+
type: number
|
|
58
|
+
default: 1
|
|
59
|
+
base_branch:
|
|
60
|
+
type: string
|
|
61
|
+
default: "main"
|
|
62
|
+
best_for: [branch_divergence]
|
|
63
|
+
requires: "XSPEC-047 Branch Drift Detection"
|
|
64
|
+
|
|
65
|
+
model_switch:
|
|
66
|
+
description: "切換至備用模型後重試"
|
|
67
|
+
config:
|
|
68
|
+
fallback_models:
|
|
69
|
+
type: "string[]"
|
|
70
|
+
description: "按優先順序的備用模型列表"
|
|
71
|
+
max_attempts:
|
|
72
|
+
type: number
|
|
73
|
+
default: 2
|
|
74
|
+
best_for: [model_degradation, prompt_delivery]
|
|
75
|
+
|
|
76
|
+
degraded_mode:
|
|
77
|
+
description: "以降級模式繼續執行(如:跳過品質驗證、以部分結果繼續)"
|
|
78
|
+
config: {}
|
|
79
|
+
result_status: "done_with_concerns"
|
|
80
|
+
best_for: [resource_exhaustion, model_degradation]
|
|
81
|
+
|
|
82
|
+
human_checkpoint:
|
|
83
|
+
description: "暫停執行,等待人工介入(提供失敗細節供判斷)"
|
|
84
|
+
config:
|
|
85
|
+
message:
|
|
86
|
+
type: string
|
|
87
|
+
description: "通知使用者的訊息"
|
|
88
|
+
best_for: [policy_violation, branch_divergence]
|
|
89
|
+
note: "所有其他策略的最終升級路徑"
|
|
90
|
+
|
|
91
|
+
recipe_schema:
|
|
92
|
+
description: "Recovery Recipe YAML 格式定義"
|
|
93
|
+
fields:
|
|
94
|
+
id:
|
|
95
|
+
type: string
|
|
96
|
+
pattern: "RR-[0-9]+"
|
|
97
|
+
required: true
|
|
98
|
+
name:
|
|
99
|
+
type: string
|
|
100
|
+
required: true
|
|
101
|
+
match:
|
|
102
|
+
required: true
|
|
103
|
+
fields:
|
|
104
|
+
failure_source:
|
|
105
|
+
type: FailureSource
|
|
106
|
+
required: true
|
|
107
|
+
severity:
|
|
108
|
+
type: "string[]"
|
|
109
|
+
values: [critical, high, medium, low]
|
|
110
|
+
description: "空或省略表示匹配所有 severity"
|
|
111
|
+
strategy:
|
|
112
|
+
type: RecoveryStrategy
|
|
113
|
+
required: true
|
|
114
|
+
config:
|
|
115
|
+
type: object
|
|
116
|
+
description: "策略特定配置,覆蓋策略預設值"
|
|
117
|
+
escalation:
|
|
118
|
+
required: true
|
|
119
|
+
fields:
|
|
120
|
+
on_exhaust:
|
|
121
|
+
type: RecoveryStrategy
|
|
122
|
+
required: true
|
|
123
|
+
description: "嘗試耗盡後的下一步策略(不得指向自身)"
|
|
124
|
+
message:
|
|
125
|
+
type: string
|
|
126
|
+
description: "升級時的通知訊息"
|
|
127
|
+
|
|
128
|
+
default_recipes:
|
|
129
|
+
description: "安裝時隨附的 5 個預設 Recipe"
|
|
130
|
+
recipes:
|
|
131
|
+
- id: RR-001
|
|
132
|
+
name: "Fix Loop for Compilation Errors"
|
|
133
|
+
match: { failure_source: compilation }
|
|
134
|
+
strategy: fix_loop
|
|
135
|
+
config: { max_attempts: 3, budget_usd: 0.50 }
|
|
136
|
+
escalation: { on_exhaust: human_checkpoint }
|
|
137
|
+
|
|
138
|
+
- id: RR-002
|
|
139
|
+
name: "Fix Loop for Test Failures"
|
|
140
|
+
match: { failure_source: test_failure }
|
|
141
|
+
strategy: fix_loop
|
|
142
|
+
config: { max_attempts: 3, budget_usd: 0.50 }
|
|
143
|
+
escalation: { on_exhaust: human_checkpoint }
|
|
144
|
+
|
|
145
|
+
- id: RR-003
|
|
146
|
+
name: "Model Switch for Degradation"
|
|
147
|
+
match: { failure_source: model_degradation }
|
|
148
|
+
strategy: model_switch
|
|
149
|
+
config: { max_attempts: 2 }
|
|
150
|
+
escalation: { on_exhaust: degraded_mode }
|
|
151
|
+
|
|
152
|
+
- id: RR-004
|
|
153
|
+
name: "Rebase for Branch Divergence"
|
|
154
|
+
match: { failure_source: branch_divergence }
|
|
155
|
+
strategy: rebase_and_retry
|
|
156
|
+
config: { max_attempts: 1 }
|
|
157
|
+
escalation: { on_exhaust: human_checkpoint, message: "Rebase 衝突,需人工解決" }
|
|
158
|
+
|
|
159
|
+
- id: RR-005
|
|
160
|
+
name: "Degraded Mode for Resource Exhaustion"
|
|
161
|
+
match: { failure_source: resource_exhaustion }
|
|
162
|
+
strategy: degraded_mode
|
|
163
|
+
escalation: { on_exhaust: human_checkpoint }
|
|
164
|
+
|
|
165
|
+
types:
|
|
166
|
+
RecoveryStrategy:
|
|
167
|
+
description: "6 個內建恢復策略"
|
|
168
|
+
values:
|
|
169
|
+
- fix_loop
|
|
170
|
+
- circuit_breaker
|
|
171
|
+
- rebase_and_retry
|
|
172
|
+
- model_switch
|
|
173
|
+
- degraded_mode
|
|
174
|
+
- human_checkpoint
|
|
175
|
+
|
|
176
|
+
RecoveryRecipe:
|
|
177
|
+
description: "恢復食譜定義"
|
|
178
|
+
fields:
|
|
179
|
+
id: "string # RR-NNN 格式"
|
|
180
|
+
name: string
|
|
181
|
+
match:
|
|
182
|
+
failure_source: FailureSource
|
|
183
|
+
severity: "string[] (optional)"
|
|
184
|
+
strategy: RecoveryStrategy
|
|
185
|
+
config: "object (optional)"
|
|
186
|
+
escalation:
|
|
187
|
+
on_exhaust: RecoveryStrategy
|
|
188
|
+
message: "string (optional)"
|
|
189
|
+
|
|
190
|
+
integration_points:
|
|
191
|
+
devap:
|
|
192
|
+
files:
|
|
193
|
+
- "packages/core/src/types.ts — RecoveryRecipe / RecoveryStrategy type"
|
|
194
|
+
- "packages/core/src/recovery-registry.ts — Registry 實作與預設 recipe"
|
|
195
|
+
- "packages/core/src/orchestrator.ts — fix loop 前查詢 Registry"
|
|
196
|
+
vibeops:
|
|
197
|
+
files:
|
|
198
|
+
- "src/types/index.ts — 獨立定義 RecoveryRecipe(AGPL 隔離)"
|
|
199
|
+
- "src/runner/recovery-registry.ts — 獨立實作"
|
|
200
|
+
- "recovery-recipes.yaml — 預設 recipe 配置"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Retry Standards - AI Optimized
|
|
2
|
+
# Source: XSPEC-067 (DEC-043 Wave 1 Reliability Pack)
|
|
3
|
+
|
|
4
|
+
standard:
|
|
5
|
+
id: retry-standards
|
|
6
|
+
name: Retry Standards
|
|
7
|
+
description: 重試策略標準 — 指數退避加抖動、重試上限、依 failure-source 分類的重試規則
|
|
8
|
+
|
|
9
|
+
meta:
|
|
10
|
+
version: "1.0.0"
|
|
11
|
+
updated: "2026-04-17"
|
|
12
|
+
status: trial
|
|
13
|
+
since: "2026-04-17"
|
|
14
|
+
expires: "2026-10-17"
|
|
15
|
+
source: XSPEC-067
|
|
16
|
+
borrowed_from: DEC-043
|
|
17
|
+
description: >
|
|
18
|
+
延伸既有 circuit-breaker 與 failure-source-taxonomy,補齊 retry 層的標準化規則。
|
|
19
|
+
避免各元件各自實作重試造成行為不一致(無上限重試、無 jitter 導致 thundering herd)。
|
|
20
|
+
與 failure-source-taxonomy 深度整合:依失敗類型決定是否重試、重試幾次、退避多久。
|
|
21
|
+
scope: universal
|
|
22
|
+
industry_reference: "Netflix Hystrix retry, Google SRE Book Ch.22, AWS Architecture Blog - exponential backoff and jitter"
|
|
23
|
+
|
|
24
|
+
guidelines:
|
|
25
|
+
- "所有重試邏輯必須使用 exponential + jitter,禁止固定間隔或無 jitter 的純指數"
|
|
26
|
+
- "重試必須有明確上限(max_attempts),禁止無限重試"
|
|
27
|
+
- "重試決策必須先參考 failure-source-taxonomy 分類,fail-fast 類別不得重試"
|
|
28
|
+
- "重試必須與 circuit-breaker 整合:OPEN 狀態下不得重試,直接 fail-fast"
|
|
29
|
+
- "每次重試都應透過遙測事件上報(retry_attempted / retry_exhausted),方便觀察無效重試"
|
|
30
|
+
|
|
31
|
+
backoff_formula:
|
|
32
|
+
name: "Exponential with full jitter"
|
|
33
|
+
formula: "wait_ms = min(cap_ms, base_ms * 2^attempt) * (0.5 + random() * 0.5)"
|
|
34
|
+
defaults:
|
|
35
|
+
base_ms: 100
|
|
36
|
+
cap_ms: 30000
|
|
37
|
+
max_attempts: 5
|
|
38
|
+
jitter_ratio: 0.5
|
|
39
|
+
rationale:
|
|
40
|
+
- "Exponential 隨重試次數指數退避,避免短時間大量請求"
|
|
41
|
+
- "Jitter ±50% 避免 thundering herd(所有 client 同時重試)"
|
|
42
|
+
- "cap_ms=30s 避免超長等待,與典型 request timeout 對齊"
|
|
43
|
+
|
|
44
|
+
failure_source_rules:
|
|
45
|
+
description: "依 failure-source-taxonomy 的 8 類 failureSource 決定重試策略"
|
|
46
|
+
rules:
|
|
47
|
+
transient_network:
|
|
48
|
+
retry: true
|
|
49
|
+
max_attempts: 5
|
|
50
|
+
base_ms: 100
|
|
51
|
+
note: "短暫網路抖動,指數退避通常可恢復"
|
|
52
|
+
rate_limit:
|
|
53
|
+
retry: true
|
|
54
|
+
max_attempts: 3
|
|
55
|
+
base_ms: 1000
|
|
56
|
+
note: "底數加大(1s)預留額度恢復時間;若 API 回傳 Retry-After 則優先採用"
|
|
57
|
+
upstream_unavailable:
|
|
58
|
+
retry: true
|
|
59
|
+
max_attempts: 3
|
|
60
|
+
base_ms: 500
|
|
61
|
+
note: "重試前先查 circuit-breaker;連續失敗觸發 OPEN 狀態"
|
|
62
|
+
tool_failure:
|
|
63
|
+
retry: true
|
|
64
|
+
max_attempts: 2
|
|
65
|
+
base_ms: 200
|
|
66
|
+
note: "工具層失敗通常非 transient,僅給 2 次機會"
|
|
67
|
+
prompt_delivery:
|
|
68
|
+
retry: true
|
|
69
|
+
max_attempts: 2
|
|
70
|
+
base_ms: 100
|
|
71
|
+
note: "多半是短暫 API 問題;超過 2 次改走 model_switch"
|
|
72
|
+
authentication:
|
|
73
|
+
retry: false
|
|
74
|
+
note: "fail-fast;憑證錯誤重試不會變對,只會浪費 quota"
|
|
75
|
+
validation:
|
|
76
|
+
retry: false
|
|
77
|
+
note: "fail-fast;input 錯誤重試結果不變"
|
|
78
|
+
policy_violation:
|
|
79
|
+
retry: false
|
|
80
|
+
note: "fail-fast;安全決策禁止繞過(對齊 security-decision 標準)"
|
|
81
|
+
quota_exhausted:
|
|
82
|
+
retry: false
|
|
83
|
+
note: "fail-fast;等 budget reset 或升級 tier,不應在同 session 內重試"
|
|
84
|
+
|
|
85
|
+
circuit_breaker_integration:
|
|
86
|
+
rule_1: "每次重試前檢查對應 breaker 的 state;若為 OPEN 立即回傳 CircuitOpenError,不消耗 max_attempts"
|
|
87
|
+
rule_2: "重試全部耗盡(retry_exhausted)計入 breaker 的 failure count"
|
|
88
|
+
rule_3: "HALF_OPEN 狀態下僅允許 1 次探針重試,不套用 max_attempts"
|
|
89
|
+
|
|
90
|
+
telemetry_events:
|
|
91
|
+
retry_attempted:
|
|
92
|
+
fields:
|
|
93
|
+
operation: string
|
|
94
|
+
attempt: number
|
|
95
|
+
max_attempts: number
|
|
96
|
+
failure_source: "FailureSource | null"
|
|
97
|
+
wait_ms: number
|
|
98
|
+
when: "每次重試前上傳(第 0 次原始呼叫不算)"
|
|
99
|
+
retry_exhausted:
|
|
100
|
+
fields:
|
|
101
|
+
operation: string
|
|
102
|
+
attempts: number
|
|
103
|
+
final_failure_source: FailureSource
|
|
104
|
+
when: "達到 max_attempts 仍失敗時上傳"
|
|
105
|
+
|
|
106
|
+
scenarios:
|
|
107
|
+
scenario_1_exponential_backoff:
|
|
108
|
+
given: "呼叫下游 API 失敗,failure_source=transient_network,已重試 2 次"
|
|
109
|
+
when: "計算第 3 次重試的等待時間"
|
|
110
|
+
then: "wait_ms = min(30000, 100 * 2^3) * (0.5 + random * 0.5) = 800 * [0.5..1.0] = 400~800ms"
|
|
111
|
+
note: "驗證退避公式正確套用 jitter"
|
|
112
|
+
|
|
113
|
+
scenario_2_fail_fast_on_auth:
|
|
114
|
+
given: "API 回傳 401 Unauthorized,偵測元件標記 failure_source=authentication"
|
|
115
|
+
when: "決定是否重試"
|
|
116
|
+
then: "立即 fail-fast,不進入退避,不計入 circuit-breaker failure count"
|
|
117
|
+
note: "authentication 類別 retry=false,避免浪費 quota"
|
|
118
|
+
|
|
119
|
+
scenario_3_circuit_open_skip:
|
|
120
|
+
given: "對應 breaker 為 OPEN 狀態,cooldown 剩 15s"
|
|
121
|
+
when: "發起重試"
|
|
122
|
+
then: "立即回傳 CircuitOpenError,不發起請求,不消耗 max_attempts"
|
|
123
|
+
note: "與 circuit-breaker 整合:OPEN 狀態下 fail-fast"
|
|
124
|
+
|
|
125
|
+
error_codes:
|
|
126
|
+
RETRY-001: "RETRY_EXHAUSTED — 達到 max_attempts 仍失敗"
|
|
127
|
+
RETRY-002: "RETRY_SKIPPED_NON_RETRYABLE — failure_source 屬 fail-fast 類別"
|
|
128
|
+
RETRY-003: "RETRY_SKIPPED_CIRCUIT_OPEN — breaker OPEN 狀態下跳過重試"
|
|
129
|
+
|
|
130
|
+
integration_points:
|
|
131
|
+
- "circuit-breaker.ai.yaml — OPEN 狀態下禁止重試,retry_exhausted 計入 failure count"
|
|
132
|
+
- "failure-source-taxonomy.ai.yaml — 依 failureSource 決定 retry/fail-fast"
|
|
133
|
+
- "timeout-standards.ai.yaml — 單次重試 timeout 不得超過剩餘 deadline"
|
|
134
|
+
- "recovery-recipe-registry.ai.yaml — retry 耗盡後交棒給 recovery recipe"
|