rainskills 0.1.21 → 0.1.23

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 (30) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +2 -2
  3. package/bin/rainskills.js +6 -0
  4. package/install.sh +3 -4
  5. package/marketplace/rainskills/.claude-plugin/plugin.json +1 -1
  6. package/marketplace/rainskills/.codex-plugin/plugin.json +1 -1
  7. package/marketplace/rainskills/skills/rainskills/SKILL.md +3 -3
  8. package/package.json +2 -2
  9. package/rainbond-app-assistant/SKILL.md +40 -1452
  10. package/rainbond-app-assistant/references/operational-reference.md +27 -0
  11. package/rainbond-app-assistant/references/routing.md +15 -0
  12. package/rainbond-app-assistant/references/runtime-gate.md +167 -0
  13. package/rainbond-app-assistant/references/workflow-rules.md +344 -0
  14. package/rainbond-app-assistant/scripts/validate_cross_skill_routing.py +637 -0
  15. package/rainbond-app-assistant/scripts/validate_progressive_loading.py +149 -0
  16. package/rainbond-app-version-assistant/SKILL.md +2 -2
  17. package/rainbond-delivery-verifier/SKILL.md +2 -2
  18. package/rainbond-env-sync/SKILL.md +2 -2
  19. package/rainbond-fullstack-bootstrap/SKILL.md +2 -2
  20. package/rainbond-fullstack-troubleshooter/SKILL.md +2 -2
  21. package/rainbond-opensource-app-deploy/SKILL.md +30 -301
  22. package/rainbond-opensource-app-deploy/agents/openai.yaml +1 -1
  23. package/rainbond-opensource-app-deploy/references/deployment-workflow.md +168 -0
  24. package/rainbond-opensource-app-deploy/references/runtime-gate.md +147 -0
  25. package/rainbond-platform-installer/SKILL.md +1 -1
  26. package/rainbond-platform-installer/scripts/installed-version.js +1 -1
  27. package/rainbond-platform-installer/scripts/runtime-state.js +20 -0
  28. package/rainbond-platform-query/SKILL.md +2 -2
  29. package/rainbond-project-init/SKILL.md +2 -2
  30. package/rainbond-template-installer/SKILL.md +2 -2
@@ -1,1476 +1,64 @@
1
1
  ---
2
2
  name: rainbond-app-assistant
3
- description: "Use whenever a user asks to deploy, run, deliver, publish, inspect, repair, or troubleshoot the current project, regardless of whether a runtime or MCP connection is configured and whether Rainbond is named. This includes a named open-source suite such as Harbor when no Compose, Helm, or image descriptor has been supplied. Trigger phrases include: 帮我把当前项目部署到 Rainbond 上 / 帮我把这个项目跑起来 / 帮我看看当前项目卡在哪 / 如果还没初始化就先初始化,然后自动继续到应该停止的位置 / 帮我处理一下这个应用 / deploy this project / run this app / publish this app / troubleshoot this project. Not for third-party public image or open-source stack deployments with a descriptor; use rainbond-opensource-app-deploy."
3
+ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect, repair, or troubleshoot source code, the current project, a source directory/package, a bare Git repository URL without a supplied Compose/Helm/image-set descriptor, or a named application without a descriptor. Trigger phrases: 帮我把当前项目部署到 Rainbond 上 / 帮我把这个项目跑起来 / 帮我看看当前项目卡在哪 / 如果还没初始化就先初始化,然后自动继续到应该停止的位置 / 帮我处理一下这个应用. Not for supplied third-party Compose, Helm, or image-set descriptors; use rainbond-opensource-app-deploy. Not for a confirmed market template; use rainbond-template-installer."
4
4
  ---
5
5
 
6
- # Rainbond App Assistant
6
+ # Rainbond App Assistant
7
7
 
8
- ## Overview
8
+ 这是源码与当前项目的 Rainbond 顶层入口。它根据现状编排 init、bootstrap、troubleshooter、delivery verifier 和显式请求的 dev-to-test promotion,但不替代下层 Skill。
9
9
 
10
- Use this skill as the high-level entrypoint for a Rainbond project workflow.
10
+ ## 路由所有权
11
11
 
12
- It coordinates existing lower-level skills so the user can say things like:
13
- - “帮我把这个项目在 Rainbond 上跑起来”
14
- - “帮我同步当前项目并修复它”
15
- - “帮我检查这个项目现在卡在哪”
12
+ - 当前项目或用户明确给出的源码 Git URL:由本 Skill 接管。
13
+ - 源码目录、源码包、私有镜像项目、裸 Git URL,以及仅给应用名称且没有描述符:由本 Skill 接管。
14
+ - 用户实际提供第三方 Docker Compose、Helm 或镜像集合描述符:转到 rainbond-opensource-app-deploy。
15
+ - 已确认是 Rainbond 本地/云端市场模板:转到 rainbond-template-installer。
16
16
 
17
- This skill does **not** replace the lower-level skills. It chooses and sequences them.
17
+ 开始前读取 [routing](references/routing.md) 做静态归属判断。只加载最终所属 Skill Runtime Gate,不得读取相邻 Skill Gate。
18
18
 
19
- The goal is to:
20
- 1. load project context
21
- 2. determine current project state
22
- 3. decide whether sync, bootstrap, troubleshooting, delivery verification, promotion to testing, or code-layer handoff is needed
23
- 4. drive the project toward a working state with the fewest possible user prompts
19
+ ## 渐进加载
24
20
 
25
- ## Default Routing Ownership
21
+ 所有 reference 必须按需加载;不得一次性加载全部 references,也不得提前读取无关 reference。
26
22
 
27
- This skill is the repository's default top-level owner for generic current-project
28
- deployment, inspection, and repair requests.
23
+ | 阶段 | 必须读取 | 禁止提前读取 |
24
+ |---|---|---|
25
+ | 初始部署或首次 Rainbond 操作 | 本根入口、[own runtime gate](references/runtime-gate.md)、[routing](references/routing.md) | 其余全部 |
26
+ | operation/context 已建立,需要编排或执行 | [workflow rules](references/workflow-rules.md);仅在核对路线或复盘时读取 [operational reference](references/operational-reference.md) | 输出与对象细节 |
27
+ | 需要对象边界或跨阶段状态语义 | [product object model](references/product-object-model.md) | 不相关工作流 |
28
+ | 需要生成最终结果或自动化契约 | [output contract](references/output-contract.md) | 不需要结果协议时不得读取 |
29
29
 
30
- If the user says things like:
31
- - “帮我把当前项目部署到 Rainbond 上”
32
- - “帮我把这个项目跑起来”
33
- - “帮我看看当前项目卡在哪”
34
- - “如果还没初始化就先初始化,然后继续”
30
+ 这里的 operation/context 是当前任务内的业务操作与 team/region/app 上下文;不得生成或传递 CLI 业务 operation ID、运行环境 ID 或 intent JSON。
35
31
 
36
- then the request should start here, even when the next concrete phase later turns
37
- out to be `project-init`, `bootstrap`, `troubleshooter`, or `delivery-verifier`.
32
+ ## Runtime Gate
38
33
 
39
- Lower-level skills should only be chosen directly when the user has already made
40
- that narrower phase explicit.
34
+ 任何 Rainbond 查询、环境连接、平台安装或变更前,必须先读取 references/runtime-gate.md。当前 Skill 在本会话首次调用 Rainbond 前强制加载且只加载自己的 Runtime Gate;当前 profile transport、鉴权、context、确认与运行时安全契约全部由该 Gate 提供。
41
35
 
42
- ## 用途速览
36
+ 不可弱化的不变量:
43
37
 
44
- 这是顶层总控 skill
38
+ - 不得绕过 Gate 选择的 transport、context 或授权边界,也不得读取相邻 Skill 的 Gate
39
+ - 401:只读调用仅可按 Gate 允许的恢复流程重试一次;写调用不得自动重放,必须先查询真实状态。403:立即停止,不做未授权重试。
40
+ - 可变调用必须先取得确认 ID,再用完全相同输入附加确认执行;不得绕过确认。
41
+ - JWT、凭据与密钥不得回显、复制到报告或通过替代 transport 绕过保护。
45
42
 
46
- 适合:
47
- - 用一句高层提示词推进整个 Rainbond 主线
48
- - 让模型自己决定是 init、bootstrap、troubleshoot、delivery verify 还是 dev-to-test promotion
43
+ ## 执行与安全
49
44
 
50
- 不适合:
51
- - 用户已经明确要求只跑某一个下层 skill
52
- - 已经转入代码修复任务
45
+ - 项目上下文只可来自当前 profile 与 Gate 允许的输入源;不得越权扫描,或把不可用的客户端文件当成事实。
46
+ - 一旦确认 source-backed 或 source ref,不得静默切换为 package/image/template 或改 branch;任何 delivery mode、workaround 或破坏性动作都需用户明确确认。
47
+ - 多 team/app 且无可靠本地提示时停止询问,禁止默认选择第一个;自动选择必须报告依据。
48
+ - 同类错误最多重试一次、同阶段最多两次,总流程默认不超过八分钟。
49
+ - 到达 code_or_build_handoff_needed 后硬停止,不自动改代码、运行本地测试、提交、推送或重试。
50
+ - 密钥只来自当前 profile 允许的输入源,永不回显或写入报告。
53
51
 
54
- 语言约定:
55
- - 规则说明、流程说明、人类可读结论:优先中文
56
- - `### Structured Output` 里的对象名、字段名、enum:保持英文 canonical 形式
52
+ 详细主线、operation/context 复用、代理规则、构建/运行时证据链、依赖、确认边界与尝试预算只在需要执行时读取 [workflow rules](references/workflow-rules.md)。
57
53
 
58
- <!-- rainskills-user-result:start -->
59
- ## 用户可见结果协议(最高优先级)
54
+ ## 简洁结果协议
60
55
 
61
- 普通用户请求部署、排障或交付验证时,内部可以维护结构化结果,但最终用户回复必须简短、中文、只呈现用户能直接使用的信息。若本节与后文 Output Format、示例或评测格式冲突,以本节为准。
56
+ 普通请求只给用户可用的中文结果:
62
57
 
63
- 部署成功时按下面的内容输出;所有名称和地址必须来自本轮真实返回值。某项无法确认时省略该项,不得猜测或推测:
58
+ - 成功:说明项目、运行环境、工作空间、应用、真实 Rainbond 页面/访问地址及本轮实际完成操作;无法确认的字段省略,禁止猜测。
59
+ - 未完成:输出“部署失败。”、一句直接原因;仅在确有安全可执行方案时增加“解决办法”。
60
+ - 用户明确要求结构化结果或自动化契约时,读取 [output contract](references/output-contract.md),不得自行发明字段、枚举或状态。
64
61
 
65
- ```text
66
- 部署成功。
62
+ ## 停止条件
67
63
 
68
- - 项目:<用户项目名称>
69
- - 运行环境:<本次实际使用的运行环境名称>
70
- - 工作空间:<本次实际部署到的 Rainbond 工作空间名称>
71
- - 应用:<创建或使用的 Rainbond 应用名称>
72
- - 运行环境地址:<Rainbond Console 或应用管理页面地址>
73
- - 应用访问地址:<部署完成后真实可访问的应用地址>
74
- - 已完成操作:<用一句话概括本轮实际完成的项目识别、应用创建、组件构建、启动和访问验证;只列真实执行过的操作>
75
- ```
76
-
77
- 部署失败或未完成时只输出:
78
-
79
- ```text
80
- 部署失败。
81
-
82
- 失败原因:<用用户能理解的一句话说明直接原因>
83
-
84
- 解决办法:<确实存在安全、可执行的解决方案时才输出;没有就省略整项>
85
- ```
86
-
87
- 只有“解决办法”确实存在并且可执行时才输出该项。默认用户回复不得出现 `Problem Judgment`、`Actions Taken`、`Verification Result`、`Follow-up Advice`、`Structured Output` 等诊断标题;不得展示内部状态码、枚举、对象字段、YAML、JSON、工具调用记录或英文状态表。只有用户明确要求结构化结果,或者自动化/评测明确要求结构化契约时,才允许输出后文的结构化格式。
88
- <!-- rainskills-user-result:end -->
89
-
90
- <!-- rainskills-runtime-gate:start -->
91
- ## 单运行环境 CLI 门禁(最高优先级)
92
-
93
- 本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true` 后,所有查询和变更直接通过本地 `~/.rainbond/bin/rainskills-tools.js` 执行。不得配置或直接调用客户端 MCP,不得执行环境枚举或业务 operation 生命周期命令,也不得生成或传递运行环境 ID、业务 operation ID 或 intent JSON。
94
-
95
- 没有运行环境时,让用户选择 Rainbond Cloud 或一个已有/新建的私有 Rainbond,并执行对应的 `runtime connect`。连接和重新授权必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT;新凭据通过 live probe 后才覆盖唯一运行环境。CLI 返回 401 时,只读调用可在 `runtime reconnect` 成功后重试一次;写调用不得自动重放,必须先查询平台真实状态。403 直接停止,不重新授权。
96
-
97
- `context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
98
-
99
- ```json
100
- {
101
- "schema": "rainskills.single-runtime-contract.v1",
102
- "package_version": "rainskills@0.1.21",
103
- "runtime_status": [
104
- "node",
105
- "<home>/.rainbond/lib/rainskills/bin/rainskills.js",
106
- "runtime",
107
- "status",
108
- "--json"
109
- ],
110
- "runtime_connect": {
111
- "saas": [
112
- "node",
113
- "<home>/.rainbond/lib/rainskills/bin/rainskills.js",
114
- "runtime",
115
- "connect",
116
- "<target>",
117
- "--saas"
118
- ],
119
- "private_existing": [
120
- "node",
121
- "<home>/.rainbond/lib/rainskills/bin/rainskills.js",
122
- "runtime",
123
- "connect",
124
- "<target>",
125
- "--rainbond-url",
126
- "<console-origin>"
127
- ],
128
- "install_private": [
129
- "node",
130
- "<home>/.rainbond/lib/rainskills/bin/rainskills.js",
131
- "runtime",
132
- "connect",
133
- "<target>",
134
- "--install-private",
135
- "--location",
136
- "<local-or-server>"
137
- ],
138
- "reconnect": [
139
- "node",
140
- "<home>/.rainbond/lib/rainskills/bin/rainskills.js",
141
- "runtime",
142
- "reconnect",
143
- "<target>"
144
- ]
145
- },
146
- "input_commands": {
147
- "context_resolve": {
148
- "argv": [
149
- "node",
150
- "<home>/.rainbond/bin/rainskills-tools.js",
151
- "context",
152
- "resolve",
153
- "--input",
154
- "-",
155
- "--skill-id",
156
- "rainbond-app-assistant"
157
- ],
158
- "stdin": {
159
- "required": [
160
- "enterprise",
161
- "workspace"
162
- ]
163
- }
164
- },
165
- "read": {
166
- "argv": [
167
- "node",
168
- "<home>/.rainbond/bin/rainskills-tools.js",
169
- "read",
170
- "<tool>",
171
- "--input",
172
- "-",
173
- "--skill-id",
174
- "rainbond-app-assistant"
175
- ],
176
- "stdin_schema_source": "tool-catalog"
177
- },
178
- "call": {
179
- "argv": [
180
- "node",
181
- "<home>/.rainbond/bin/rainskills-tools.js",
182
- "call",
183
- "<tool>",
184
- "--input",
185
- "-",
186
- "--skill-id",
187
- "rainbond-app-assistant"
188
- ],
189
- "stdin_schema_source": "tool-catalog"
190
- },
191
- "call_confirm": {
192
- "argv": [
193
- "node",
194
- "<home>/.rainbond/bin/rainskills-tools.js",
195
- "call",
196
- "<tool>",
197
- "--input",
198
- "-",
199
- "--skill-id",
200
- "rainbond-app-assistant",
201
- "--confirm",
202
- "<confirmation-id>"
203
- ],
204
- "stdin_schema_source": "same-confirmed-input"
205
- }
206
- }
207
- }
208
- ```
209
- <!-- rainskills-runtime-gate:end -->
210
-
211
- 受限沙箱(包括 Codex)执行本地状态命令时,必须申请用户级受保护目录访问权限;在 Codex 中使用 `require_escalated`。不得修改 `~/.rainbond` 权限、复制受保护状态到工作区,或因沙箱权限错误建议重装。
212
-
213
- 涉及浏览器或设备授权的 `runtime connect`,以及恢复/安装场景中的 `rainskills <target> --self-hosted`,必须在附加交互终端(TTY)中运行;在 Codex 中设置 `tty: true` 并保持进程附着直到授权完成。禁止通过非交互命令要求用户粘贴 JWT;非交互模式只可复用已存在的受保护凭据。
214
-
215
- 执行优化:同一会话内只检查一次 Node.js(首次使用本地 CLI 前);仅在 Node.js 或 Rainskills 安装、升级,或 PATH 变更后失效。固定 launcher 和 argv 已在本 Skill 中,禁止读取、搜索或探测 `rainskills.js`,也禁止执行 `npm root -g`。每个新的业务操作仍需要刷新一次环境列表;带已有 `operation_id` 或 `onboarding-id` 的续接复用已绑定的环境 ID,不重复枚举环境。
216
-
217
- <!-- rainskills-runtime-routing:start -->
218
- ## 缺少运行环境时
219
-
220
- 先确认 intent 属于 new scope 还是 existing scope;确认前不展示环境选项。
221
-
222
- ### 意图不明确
223
-
224
- 用户请求没有明确指向新应用或已有应用时,只问:“这是要部署新应用还是管理已有应用?”确认前不连接运行环境,也不展示任何环境选项。
225
-
226
- ### 新应用
227
-
228
- 用户明确要部署新应用后,先执行本地 launcher + `["runtime", "message", "--id", "new-application-environment"]`。收到 `[RAINSKILLS_USER_MESSAGE_BEGIN:<id>]` 与对应 END marker 后,只原样输出两者之间的正文,不输出 marker,不得总结、改写、调整项目符号或追加其它说明。下方文案仅用于核对,不得由 agent 自行生成:
229
-
230
- > 可以,我会帮你完成应用识别、构建、部署和访问验证。
231
- >
232
- > 不过目前还没有可用的应用运行环境。
233
- >
234
- > 你刚安装的 Rainskills 是负责“部署”的 AI 助手,它会分析项目并执行部署流程;Rainbond 负责为应用提供稳定运行环境。
235
- >
236
- 此时只保存用户已经明确提供的 intent 字段。`deploy`/`create` 可以只保存 `type`;不得为了构造 runtime intent 提前补参数,平台安装完成前不得询问应用来源,包括本地项目路径、Git 仓库 URL、镜像地址或安装包路径。运行环境连接并通过验收后,恢复到 `project-analysis`,再识别当前项目或询问缺失的应用来源。
237
-
238
- #### 选择运行环境
239
-
240
- 请提示“请选择应用要运行的环境:”,并只显示:
241
-
242
- 1) 云端环境(免费体验)
243
- 2) 本机环境
244
- 3) 独立服务器
245
- 4) 已有 Rainbond
246
-
247
- 选择 1 时执行 `saas` route;选择 2 时执行 `install-private` route,并在完整 argv 中使用 `["--location", "local"]`;选择 3 时执行 `install-private` route,并使用 `["--location", "server"]`;选择 4 时执行本地 launcher + `["runtime", "message", "--id", "private-console-origin"]`,收到地址后执行 `private-existing`。不得显示“私有环境”或部署位置中间层,不得在平台安装器中重复询问部署位置,也不得在环境准备完成前询问应用来源。
248
-
249
- ### 已有应用
250
-
251
- 用户明确要查询、排障、修改或验证已有应用时,使用与动作匹配的第一句话,只提供 `Rainbond Cloud` 或承载目标应用的`已有私有 Rainbond`。选择已有私有 Rainbond 时执行本地 launcher + `["runtime", "message", "--id", "private-console-origin"]` 并原样输出。已有应用不得安装新平台,也不得进入 install-private。
252
- <!-- rainskills-runtime-routing:end -->
253
-
254
- ## 硬规则
255
-
256
- 以下规则优先级最高。若后文示例、详细说明或历史注释与这里冲突,以这里为准。
257
-
258
- 1. 只读取当前项目目录中的 `rainbond.app.json`、`.rainbond/local.json`、环境文件和 secrets 文件。
259
- 不允许扫描 `$HOME`、上级目录或其他仓库来“补绑定”。
260
- 2. **team / app 智能选择**:
261
- - 单个 team 可访问 → 直接用,不询问。
262
- - 多个 team 但 manifest(`rainbond.app.json` / `.rainbond/local.json`)显式指定了 `team_name` 且该 team 在可访问列表里 → 直接用,在报告里明确说"已选 team = X(来自 manifest)"。
263
- - 多个 team 且无 manifest 提示 → 停下来询问用户,**禁止**静默选 `default` / 第一个 / 任意已有 team。
264
- - app 选择同上逻辑:manifest 指定且可解析 → 直接用;无提示且多候选 → 询问。
265
- - 任何自动选择的结果都必须在最终报告里以"已选 X(理由:来自 manifest / 单一可选)"形式告知,邀请用户覆盖。
266
- - 每个 Rainbond MCP 工具边界都要把十进制字符串 `app_id` 规范化为正整数;非数字 ID 必须拒绝。
267
- 3. 单入口主线一旦触发:
268
- `project-init -> bootstrap -> troubleshooter -> delivery-verifier -> version-assistant -> testing-app delivery-verifier`
269
- 应按 gate 自动继续,不要在中途停成“下一步建议”。
270
- 4. `project-init` 成功 linked 后,如果当前 run 是单入口部署/开发到测试主线,必须自动继续到 `bootstrap`。
271
- 5. 当前项目一旦被判定为 `source-backed`,不能静默改成 `package` 或 `image`。
272
- transport 代理只改“怎么拉”,不改 delivery mode。
273
- 6. **传输代理自动决策(Git URL + image 公网拉取统一处理)**:当组件源指向**已知有可工作代理的公网服务**时,**默认自动套用代理**,不打断流程问用户,在最终报告里明确告知"已用 X 代理拉取 Y",邀请用户覆盖。其它情况按下面分类处理。
274
-
275
- **已知可工作的代理 pair(限定清单 — 这里必须用清单,不能用 principle,因为代理 URL 是事实,不能让模型推断)**:
276
- - `github.com` Git URL → `https://ghfast.top/<原完整 URL>`(含 `https://github.com/...`、`https://raw.githubusercontent.com/...`)
277
- - `docker.io` 容器镜像(含裸 `nginx:latest`、`library/...` 这种隐式解析为 `docker.io/library/...` 的引用)→ `docker.1ms.run/<dockerhub-path>`
278
-
279
- **其它公网 registry / Git 托管**(`quay.io`、`gcr.io`、`ghcr.io`、`k8s.gcr.io`、`registry.k8s.io`、`nvcr.io`、`mcr.microsoft.com`、`public.ecr.aws`、`gitlab.com`、`codeberg.org` 等及其它公网服务):
280
- - **禁止瞎拼代理 URL**(如 `docker.1ms.run/quay.io/...`、`docker.1ms.run/nvcr.io/...` 都不是有效路径 — 这些公网代理只针对自己声明的源仓库工作)
281
- - 默认**先用原 URL 试**,不主动套代理
282
- - 如果用户在消息里明确给出了代理 URL(如 `请用 https://my-proxy/quay.io/calico/node`),照用
283
- - 如果出现拉取失败(`ImagePullBackOff`、`Manifest not found`、`connection refused`),**这时才**询问用户:"`quay.io/...` 拉取失败,可能是网络问题。您是否有可用的代理?或者继续重试原 URL?"
284
-
285
- **私有 / 自建 registry**:直接用原 URL,**绝不代理**。判断特征(principle):URL 包含 `.internal` / `.local` 后缀、企业自有域名(`harbor.<corp>.com`、`registry.<corp>.cn`)、IP+端口(`10.x.x.x:5000`、`<host>:443/...`)、云厂商私有仓库子域名(`registry.cn-*.aliyuncs.com`、`<aws-account>.dkr.ecr.<region>.amazonaws.com` 等用户专属路径)。模型用通用知识识别,不需要等清单。
286
-
287
- **已在镜像源的 URL**(前缀已是 `docker.1ms.run`、`m.daocloud.io`、`mirror.gcr.io`、`ghfast.top/...` 等):直接通过,不重复代理。
288
-
289
- 一次 run 内复用同一代理前缀,不并存多个。用户明确说"不用代理"或"用原始地址" → 当次 run 内对所有 in-scope URL 都跳过代理。
290
-
291
- > 编号说明:原 Iron Law 7(image 代理 ask once)已合并到本条;后续 Iron Law 编号保留原值(8、9、10…),不重编号以免破坏跨规则引用。
292
- > 措辞说明:代理 URL 是**事实信息**(哪个代理服务真的能 proxy 哪个源),必须写清单 — 这跟 Iron Law 37 把"基础设施软件"写成 principle 是不同性质。不要把这里的清单也"principle 化",否则模型会瞎拼无效代理 URL。
293
- 8. 一旦 source ref 已确定,不能静默改 branch/ref。
294
- 分支不存在时必须停住并报告 source definition needs confirmation。
295
- 9. `check_uuid` / `event_id` 默认不是标准 source create 的前置条件。
296
- 除非后端明确返回它们必需,否则不能把它们当 blocker。
297
- 10. 如果 source create 返回 `multiple services detected` 或等价的多组件源码歧义,必须停住,要求用户明确选择策略。
298
- 不允许自动切到 local package、手工上传、模板安装或其他 workaround。
299
- 11. 如果进入 `code_or_build_handoff_needed`,必须硬停止。
300
- 不允许自动改代码、跑本地测试、commit、push、自动重试。
301
- 12. `delivery_state` 只表示 source app。
302
- 在没有运行 `delivery-verifier` 之前必须是 `null`。
303
- `promotion_result` 只表示 snapshot 和 testing app;未进入 promotion 时必须是 `null`。
304
- 13. 顶层主线必须有尝试预算:
305
- - 同一类错误签名最多重试 1 次
306
- - 同一阶段最多尝试 2 次(首次 + 1 次重试)
307
- - 单次主线总时长默认不应超过 8 分钟;超时后必须停止并汇报当前停点。
308
- 14. 任何 delivery mode 或 workaround 策略切换都不允许隐式发生。
309
- source -> package、source -> image、source -> template 都必须先得到用户明确确认。
310
- 15. 如果用户明确在问“为什么构建失败”,顶层必须优先走 `component events -> build logs -> runtime logs` 的构建失败证据链。
311
- 不要把运行容器日志当第一现场。
312
- 16. 如果用户要求调整源码构建参数,优先走 `rainbond_manage_component_envs(operation=replace_build_envs, build_env_dict=...)`。
313
- 不要把语言构建参数塞进 `build_info`。
314
- 17. 如果源码检测同时命中 Dockerfile 和语言构建,按 `rainbond-fullstack-bootstrap` 的 Build Mode Selection 优先级链解决:manifest `source.build.strategy` 优先 → 启发式按 Dockerfile 分类 + 意图信号判断("语言 buildpack 能否产生等价运行时行为",原则驱动而非固定清单)→ 真正模糊时才问一次并建议用户写回 manifest。决策必须双轨可审计:prose 输出"Build mode for `<name>`: `<picked>` (`<source>` — `<reason>`; to override: `<hint>`)"逐组件展示,且 bootstrap 的结构化输出 `deployment_plan.workflow.build_strategy_decisions[<name>]` 同步记录(仅给有 dual detection 的组件填)。`dockerfile` 决策映射到 `rainbond_create_component_from_source` 的 `prefer_dockerfile_when_detected = true`。详见 `rainbond-fullstack-bootstrap/references/source-build-parameter-guide.md § Build Mode Selection`。
315
- - **恢复例外按状态决定**:`checking` / `checked` / 未完成组件可以通过 `rainbond_get_component_check_result(prefer_dockerfile_when_detected=true)` 在原拓扑中取得 Dockerfile 证据,禁止删除。只有 `create_status=complete` 的 CNB 组件不存在通用原地切换能力时,才允许在已保存 topology and configuration snapshot、已向用户展示该完成状态并获得 explicit user confirmation 后删除并重建;任一证据缺失时只读停止。
316
- 18. 当前 MCP 不支持显式 `dockerfile_path` 时,不要在顶层编排里承诺该能力。
317
- 19. 对 reverse-proxy full-stack 项目,不要只因为根路径 URL 存在就把它当作最终交付成功或 Fast Path 的可信 URL;同 host 的 backend 路径(通常是 `/api`)必须也一致可用,或明确停在 blocker。
318
- 20. **组件依赖与连接变量管理**(合并自原 20-23 四条):多组件拓扑里,provider/consumer 关系必须用显式依赖 + provider 侧连接变量管理,不要让 consumer 端硬编码或重复声明。
319
-
320
- **可执行工具(fact)**:
321
- - 显式依赖:`rainbond_manage_component_dependency` — 不要回答"MCP 没有依赖接口";调用失败时按 MCP/控制面真实错误报告,不要描述为工具不存在
322
- - Provider 连接变量:`rainbond_manage_component_connection_envs(scope=outer)` — 这是 provider 暴露给 consumer 的接口面
323
- - Consumer 自身的本地 env:`rainbond_manage_component_envs` — 仅放该 consumer 真正本地的值
324
-
325
- **判断顺序(principle)**:
326
- - 拓扑里出现 provider/consumer 关系(`depends_on`、反向代理链路、运行时日志暴露的连接错误)→ 用 `rainbond_manage_component_dependency` 建显式依赖
327
- - 共享连接信息(数据库连接串、缓存地址、消息队列 broker 等任何"provider 拥有的连接 fact")→ 配在 provider 的 connection envs 上,**不要**在每个 consumer 上重复写
328
- - 运行时报 `connection refused` / `ENOTFOUND <provider-name>` / 错 host / 错 port / 缺密码等连接类错误 → 先看 provider connection env / dependency alias / compatibility env,**不要**把 baseline 里的硬编码主机名当成事实
329
- - 多组件拓扑进入交付验收前 → 必须跑一遍依赖完整性 gate(列已接受边 → 查现有依赖 → 补齐缺失 → 再次验证依赖摘要)。手工创建镜像组件、Compose fallback 路径、组件能独立启动都**不能**跳过 gate
330
- - **配置覆盖 gate(backend 组件,设完 env 后、宣布健康/可交付前必跑)**:从 `rainbond_get_component_summary` 枚举该组件挂载的 config-file 卷。若有卷挂到已知配置路径(`config.yml` / `application.yml` / `application.properties` / `.env` / `nginx.conf` / `*.conf`),运行态有效配置由该文件决定而非 env(mounted config-file > env > 镜像默认值)。这时必须警告"env 可能被挂载的配置文件覆盖",并先确认该文件反映了预期值,再宣布交付健康。比较配置值用于该 gate 是允许的,但**禁止**回显原始文件内容或密钥明文,只报结构化不一致。文件内容无法用当前 MCP 能力读取时,显式标注覆盖风险并停下来让用户确认,不要默默改 env 就当成功
331
-
332
- 具体的 provider 命名约定、connection env 变量名(`DB_*` / `REDIS_*` / `KAFKA_*` 等是示例,按 provider 文档实际名字为准)、以及依赖 alias 细节,详见 bootstrap modules/30-creation-rules.md 的相关章节。
333
- 24. 不要自动拉起本地 Docker Desktop/OrbStack、执行本地 Docker build/push、或推送临时镜像作为兜底;这属于 delivery-mode 策略切换,必须先得到用户明确确认。
334
- 25. 每次运行内部仍必须形成 `AppAssistantResult` 结果对象,但默认用户答复不一定暴露 YAML。
335
- 当 `source_app_delivery` 的 runtime healthy、没有 blocker、控制台部署位置和公网访问地址都已确定,且 delivery 已 `delivered` 或只剩浏览器人工确认时,默认使用简洁中文交付报告,不追加 `### Structured Output`。
336
- 26. 只有在自动化/评测明确要求结构化契约,或用户明确要求 YAML、JSON、调试详情、内部状态对象时,才把 `AppAssistantResult` 渲染为最终 fenced `yaml`。部署失败、仍在构建、存在 blocker/handoff/身份歧义或进入 dev-to-test promotion 都不是默认暴露 YAML 的理由。
337
- 27. 如果本次使用了 Git、镜像仓库或其他传输代理,必须在默认交付报告的处理记录或注意事项中说明;在结构化模式下也必须写入 `actions_performed[].details`。
338
- 代理事实属于执行记录,不是强制暴露 YAML 的理由。
339
- 28. `rbd-*` 组件(rbd-gateway、rbd-api、rbd-worker、rbd-chaos、rbd-db、rbd-mq、rbd-monitor、rbd-node 等)是 Rainbond 平台自身的基础设施组件,不是用户应用组件。
340
- - 可以用 `rainbond_query_region_rbd_components` 查询并展示它们的状态
341
- - 不能通过 MCP 对它们执行重启、部署、修改等写操作;当前 MCP 工具集不支持此类操作
342
- - 如果用户要求操作这些组件,明确告知:需要通过 Kubernetes 命令(如 `kubectl rollout restart deployment/<name> -n rbd-system`)或 Rainbond 集群管理控制台进行,超出本技能的操作范围,不要假装可以执行
343
- 28a. 已知 `service_id` 的组件在构建、部署或运行操作后失败或立即异常时,调用 `rainbond_get_operation_failure_context({team_name, region_name, app_id, service_id, event_id?})`,按其 `classified_reason` 决定停下、只读核实或低风险修复;`unknown` 回退既有证据链,禁止盲目重放写操作。CLI 在确认令牌生成前报告的 missing/invalid field 属于参数校验失败,尚未进入组件操作:按 Console Tool schema 修正参数一次,不调用 failure context,也不查询组件残留。
344
- `event_log_tail` 只作为敏感诊断证据使用,绝不能复制、引用或向用户展示其原文;输出只能使用 `classified_reason`、非敏感摘要和已脱敏字段。
345
- 28b. 运行态或交付健康检查先调用 `rainbond_get_app_health_overview`;仅 `abnormal` 或 `unknown` 组件再读取 component summary、日志、事件或存储明细。
346
- 29. **仅给 bare Git URL 时默认 root + 空 `subdirectories`**:当用户给的只是一个 Git URL(无本地 manifest、无明确子目录提示),默认 `subdirectories=""`(仓库根)进入 source 检测,让后端判断这个仓库结构。**不要**先问用户"根目录还是子目录"。
347
- - 单项目仓库(一个 buildable root)→ 后端检测通过,正常 build
348
- - 多组件 / 多 example 仓库 → 后端返回 `multiple services detected` 或等价歧义信号 → 按 Iron Law 10 停下问用户选哪个子目录
349
- - 模型**禁止**凭训练知识枚举子目录或猜测路径(由 Iron Law 36 强制 — `subdirectories` 是受 verbatim 保护的字段之一)
350
- - 把"是否需要选子目录"这个判断**外包给后端检测**,不要前置询问;前置询问只在用户的需求文本本身就说了"我只要这个仓库的 X 子目录"这类显式信号时才有意义(这时直接 verbatim 用用户给的子目录字面值)
351
- 30. 源码创建一旦失败,**绝对禁止**第二次调用 `rainbond_create_component_from_source` 来"换参数重试",也**绝对禁止**通过 `rainbond_delete_component` 删掉失败组件再 create 这种伪装手段绕过预算。
352
- `rainbond_create_component_from_source` 是"检测 + 创建 + 构建"三合一工具,**不是幂等重试工具**,每次调用都会写入一个新的 `service_id`。调用报错不代表组件没建出来——组件行、端口、env、依赖可能已经存在,错误只发生在下游检测或构建阶段;不能凭"上次 create 调用我没拿到 service_id 所以肯定没建出来"做臆测。
353
- 本轮任何源码失败(包括"源码目录不存在 / 子目录识别不到 / 多组件歧义 / 仓库不可达 / 检测识别不到语言 / 构建失败"等)之后,第二个动作**必须**按以下纪律走:
354
- - 第一步永远先 `rainbond_query_components` 查目标 app,按 `service_cname` 或 `k8s_component_name` 匹配;只要查到一条同名/相近的组件,就视为已存在
355
- - 命中已存在:
356
- - 同 `git_url` 同 `code_version`,只想重跑构建 → `rainbond_build_component(service_id, build_info=...)`
357
- - 源码定义改了(`git_url` / `code_version` / `subdirectories` / `server_type` / 凭据) → `rainbond_update_component_build_source` 然后 `rainbond_build_component`
358
- - 只调构建参数 → `rainbond_manage_component_envs(operation=replace_build_envs, build_env_dict=...)` 然后 `rainbond_build_component`
359
- - 未命中(`rainbond_query_components` 确认目标 app 下不存在任何对应组件)才允许重新调 `rainbond_create_component_from_source`,且仍然受 Iron Law 14 的尝试预算约束。
360
- 典型反例(**禁止**):第一次报"源码目录不存在" → 第二次换个 `subdirectories` 再 create → 第三次又换大小写再 create。每次都会产出新的 service_id,留下多个垃圾组件需要用户清理。正确路径:先 `rainbond_query_components`,如果已经留下了某个 `java-maven-demo` 组件,就 `rainbond_update_component_build_source` 改 `subdirectories` 再 `rainbond_build_component`;只有确认 app 下完全没有同名组件,才可以重新 create,并且必须遵守"同一阶段最多 2 次"。
361
- **以 `service_cname` 为预算基本单位**:Iron Law 14 的"同一阶段最多尝试 2 次"按 `service_cname` 累计计数,**`rainbond_delete_component` 不重置这个计数**。换句话说,对同一个 `service_cname`(例如 `java-maven-demo`)在本轮 run 内 `create_from_source` 类工具的调用总次数最多 2 次,不管中间有没有 `delete_component` 把上一次的失败组件清掉;超过即必须停下来按下面"用户输入错误"流程走。
362
- **用户输入错误必须停下来问用户,不允许猜参数**:当源码检测明确报"源码目录不存在 / 语言识别失败 / 仓库不可达 / 凭证错误"等**用户输入相关**的错误时,根因是用户给的 `git_url` / `subdirectories` / `code_version` / 凭证本身有问题——这类错误**不能通过 AI 自己换参数**(去掉 subdirectories、改大小写、换分支名、换 case)来解决。必须**停下来**显式询问用户:
363
- - 列出已尝试的参数组合和对应的错误信息
364
- - 请用户确认仓库的真实子目录路径(建议用户在浏览器打开仓库或贴 tree 截图)
365
- - 或者请用户提供另一个分支 / 凭证 / 子路径
366
- - **不允许**根据"模型对该仓库的先验知识"猜常见名字(Java-maven-demo、java_maven_demo、demo/java-maven 等)
367
- - 这与 Iron Law 29 入口"必须问用户"配套:29 管入口、30 管中途用户输入验证失败的二次询问。
368
- 猜测换参数 + 删-再-create 循环是典型 anti-pattern,server 端可能直接 reject 重复 create 调用。
369
- 31. **任何 Rainbond MCP 写工具调用之前**,必须先按下面的映射调用对应的 `select_skill_<id>` 工具,把该阶段的执行手册加载进会话上下文;没先调 `select_skill_<id>` 就直接动手等于**无授权操作**,是 Iron Law 违反。
370
- 触发动作(凡是这类,第一次调之前都必须先 `select_skill_<id>`):
371
- - 创建/更新/部署组件:`rainbond_create_component_from_source`、`rainbond_create_component_from_image`、`rainbond_create_component_from_package`、`rainbond_create_component`、`rainbond_build_component`、`rainbond_update_component_build_source`、`rainbond_change_component_image`
372
- - 包上传事务:`rainbond_init_package_upload`、`rainbond_delete_package_upload`;包内容必须由 bootstrap 的客户端 helper 上传,完成后再用上面的 event-based package create
373
- - 组件配置:`rainbond_manage_component_envs`、`rainbond_manage_component_ports`、`rainbond_manage_component_connection_envs`、`rainbond_manage_component_dependency`、`rainbond_manage_component_storage`、`rainbond_manage_component_probe`、`rainbond_manage_component_autoscaler`
374
- - 应用操作:`rainbond_operate_app`、`rainbond_horizontal_scale_component`、`rainbond_vertical_scale_component`、`rainbond_delete_component`
375
- 映射表:
376
- - 当前 run 是**首次部署/创建组件/补齐拓扑**(含从源码/镜像创建,以及客户端 package upload + event-based package create) → 在第一个 MCP 写调用之前调 `select_skill_rainbond-fullstack-bootstrap`
377
- - 当前 run 是**排查运行态/构建失败**(CrashLoopBackOff / ImagePullBackOff / 构建报错 / 端口/依赖不通) → 在第一个 MCP 写调用之前调 `select_skill_rainbond-fullstack-troubleshooter`
378
- - 当前 run 是**交付验收**(验证 URL 可达、reverse-proxy 路径连通) → 调 `select_skill_rainbond-delivery-verifier`
379
- - 当前 run 是**开发到测试 promotion**(创建快照 + 测试 app) → 调 `select_skill_rainbond-app-version-assistant`
380
- - 当前 run 是**模板安装**(本地/云端 Rainbond 应用模板) → 调 `select_skill_rainbond-template-installer`
381
- 规则细节:
382
- - `select_skill_<id>` 本身不需用户审批、不消耗 MCP,但它的调用是**前置门控**,没调不允许走下去
383
- - 一个 skill 在同一次 run 内只需调一次(重复调用工具会返回 "already active" ack)
384
- - **判断依据**:用户消息中只要含"部署 / 跑起来 / 上线 / 创建组件 / 发布"等部署意图,且当前 app 还没有对应组件,就必然要先 `select_skill_rainbond-fullstack-bootstrap`,不论用户是不是显式说"先 deep dive"
385
- - 如果一次 run 内场景跨阶段(先创建后排障),按需追加 `select_skill_<id>`,旧的不会被卸载
386
- 正确路径:用户说"试试 maven-demo" → 你直接调 `rainbond_update_component_build_source(service_id=已知的, subdirectories='maven-demo')` → `rainbond_check_component(service_id=已知的, is_again=true)` → 轮询 `rainbond_get_component_check_result` 直到拿到新一轮 `check_event_id`/`check_uuid` 的结果。
387
- 32. **简短回复继承上一轮被中断的操作**:当上一轮你向用户提了问、或在 prose 里邀请用户回复("回复继续 / check / OK / 完成 / 重试" 等),用户给了简短或单值回复("继续"、"OK"、"试试 X"、"对的就是 Y"、"换 master"),你的**下一个动作必须基于 priorTurnMessages 的最新状态继续上一个被中断的操作**,**禁止**把它当成一次"全新的开始"。
388
- - 看 priorTurnMessages 里上一条 assistant 消息:以问号结尾 / 含"回复 X / 你看 / 是否 / 请确认 / 请选" → 视为对你提问的回答
389
- - 用户上一轮如果在等"build 完成"、"poll status"、"check 进度"等异步状态,简短回复就是"继续轮询" → 直接调对应的状态查询工具(`rainbond_get_component_summary` / `_build_logs` / `_events` 等)
390
- - 用户上一轮在等"换参数后的重新检测结果",简短回复就是"用新值重跑" → 直接调修改类工具(update_build_source → check → poll,见 Iron Law 33)
391
- - **禁止**:本轮重新走"加载 skill / 询问意图 / 查 app 详情 / 列能力清单"的初始化流程
392
- - **例外**:用户消息明显是新任务("换个项目"、"算了别部署了"、"先停下"),按新任务处理
393
- - 信号词识别:"继续 / check / OK / 完成了吗 / 现在怎样 / 进度 / 试 X" 这类短词 → 多半属于回答;超过一句完整描述新任务的才算 fresh intent
394
- 33. **`rainbond_update_component_build_source` 只改 DB 不触发检测**,调完之后下一个 MCP 写调用**必须**是 `rainbond_check_component(service_id=..., is_again=true)`,不允许中间夹任何其他工具,也不允许跳过它直接读 check_result 或调 build。
395
- 背景(必读):后端 `update_component_build_source` 视图仅把 `git_url`/`subdirectories`/`code_version`/凭证字段写进 DB(`service.save()` 结束),**没有调用 `app_check_service.check_service`**。因此:
396
- - 改完 build_source 后调 `rainbond_get_component_check_result` → 返回的依然是**上一轮**(最初 create 时)的 `check_uuid` 和 "源码目录不存在" 旧结果,给人"我的修改没生效"的假象,实际是检测根本没重跑
397
- - 改完 build_source 后调 `rainbond_build_component` → 组件还停留在 `service_source=source_code` + 上轮检测未通过的状态,build 任务会被卡在 `checking`,无法真正启动
398
- - 唯一能让后端重跑源码检测的方式是 `rainbond_check_component(is_again=true)`(对应 `app_check_service.check_service(team, service, is_again=True, ...)`,会清掉旧的 `check_uuid` 并发起新一轮 check_event)
399
- 强制时序模板:
400
- ```
401
- rainbond_update_component_build_source(service_id, git_url?, subdirectories?, code_version?, ...)
402
- ↓ 立刻
403
- rainbond_check_component(service_id, is_again=true)
404
- ↓ 拿到新的 check_event_id / check_uuid
405
- rainbond_get_component_check_result(service_id) # 轮询直到 check_status != "checking"
406
- ↓ 通过
407
- rainbond_build_component(service_id, build_info=...)
408
- ```
409
- 禁止序列:
410
- - `update_component_build_source` → `get_component_check_result`(中间没 `check_component`)
411
- - `update_component_build_source` → `build_component`(中间没 `check_component`,组件仍 `checking`,build 必失败)
412
- - 多次 `update_component_build_source` 之间不夹 `check_component`(等价于在改了 DB 但没触发检测的情况下又改一遍,每次轮询的还是同一个旧 `check_uuid`)
413
- 与 Iron Law 30 配套:30 管"换参数重试"的预算(同 `service_cname` 最多 2 次 create / 同 service_id 同字段最多 N 次 update),33 管"改完后必须走完一个完整 check 闭环"。两者一起堵住"猜参数 → 改了又不重检测 → 又看到旧错误 → 再猜"的死循环。
414
- 34. **service_id provenance:任何 MCP 写工具传入的 `service_id` 必须有明确出处**,不允许凭模型记忆或上下文里飘着的 UUID 猜。
415
- 合法的 `service_id` 来源(按优先级):
416
- - 本会话内 `rainbond_query_components` 的返回结果(最新一次)
417
- - 本会话内 `rainbond_create_component_*` 工具的返回值
418
- - `session.localBinding.serviceId` / `priorTurnMessages` 里同一 `service_cname` 的 ack
419
- 不合法的 `service_id` 来源(**禁止**):
420
- - 从对话历史里随手抓一个看起来像 UUID 的字符串(可能是 `check_event_id` / `check_uuid` / `event_id` / 历史 service_id)
421
- - 凭"我记得是这个"或"上次也是这个 ID"做猜测
422
- - 用户消息里粘的、但本会话没验证过的 ID
423
- 强制流程:动手前如果不能 100% 确定 `service_id` 出处,**第一动作**必须是 `rainbond_query_components({enterprise_id, app_id})`,必要时携带 `query=<service_cname 或 service_id>`,按 `service_cname` 或 `k8s_component_name` 匹配出真实 `service_id`,再调写工具。
424
- 反例(**禁止**):日志里出现"修改组件 `7059eb62cccc3a16f22c9415c905bbcc` 的构建源" — 这个 ID 在本会话所有 query 结果里都没出现过,是模型从某处幻觉出来的。正确做法:调 update 之前先 `rainbond_query_components` 拿到真实 `service_id`,再 update。
425
- 与 Iron Law 31 配套:31 管"写工具前必须 select skill",34 管"写工具的 service_id 必须有明确出处"。两条共同把"模型自由发挥参数"这条路堵死。
426
-
427
- **同样的 provenance 规则对 `event_id` 生效**:调 `rainbond_get_component_build_logs` / `rainbond_get_app_upgrade_record` 等需要 `event_id` 的工具时,`event_id` 必须是**真实 UUID**(如 `805f6397871d467b968d14c3575082a6`),合法来源仅限:
428
- - 本会话内 `rainbond_get_component_events` 返回的 `events[*].event_id`
429
- - 本会话内写工具(`rainbond_build_component` / `rainbond_operate_app` / `rainbond_check_component` 等)响应里的 `event_id` / `build_event_id` / `check_event_id`
430
-
431
- 不合法 `event_id` 来源(**禁止**):
432
- - `rainbond_get_component_summary` 返回的 `recent_events[*].ID` — 这是**数据库自增行号**(如 `17740`),**不是** UUID
433
- - 任何看起来是短整数的字段(4-6 位数字)
434
- - 历史会话里飘着的、本会话未通过 events 查询验证过的字符串
435
-
436
- 强制流程:调用任何 `event_id`-required 工具前,如果不能 100% 确定 `event_id` 出处,**第一动作**必须是 `rainbond_get_component_events(team_name, region_name, app_id, service_id, page=1, page_size=10)`,从 `events[*].event_id` 拿真实 UUID,再调下游工具。
437
-
438
- 反例(来自真实回归 case `cs_1779149681822_3u`,2026-05-19):模型从 `rainbond_get_component_summary` 响应的 `recent_events` 段看到形如 `{"ID": 17740, "event_id": "...", "opt_type": "build-service"}`,直接把 `17740` 当成 `event_id` 传给 `rainbond_get_component_build_logs`,工具返回 `items: []`(找不到该 UUID 的日志)。正确做法:从同一 `recent_events[i].event_id` 字段取出 UUID 字符串,或调 `rainbond_get_component_events` 重查。
439
- 35. **会话内部叙述纪律 + 内部 preflight 工具不要主动调**。下列四类是"内部会话状态",对用户**无信息量**,禁止外漏到 assistant 可见消息:
440
- - **`select_skill_*` 工具调用本身**:这是 server 内部 hookup,把指定 skill 的执行手册拼到 system prompt 用的。调用前**不要**说"我先加载 bootstrap 手册"、"现在调用 select_skill_...";调用后**不要**说"Bootstrap 手册已加载"、"skill ready" 这类回声。server 返回的 `loaded_skill` / `already active` ack 是给你看的内部信号,**直接进入下一个真实工具调用**,保持沉默。
441
- - **`rainbond_get_current_user`**:不得由 Agent 单独调用。企业、工作空间和集群上下文统一由受保护的 `context resolve` 命令解析并绑定到本次 operation;只有 CLI 明确返回需要选择时才询问用户。
442
- - **`rainbond_query_components` 同入参重复轮询**:服务端 30s 内的同 args 调用会走缓存;你**不要**在每个新 user turn 开头都"先查一下组件列表",priorTurnMessages 里上一次的 query 结果在 contextSignature 不变时仍然有效。
443
- - **规则推理过程 / MCP 工具内部限制 / 分类决策叙述**:你内部基于哪条 Iron Law / hard rule / 推断信号做的决策、具体 MCP 工具签名 / 字段限制、对组件 / 服务的分类判断("ClickHouse 是公认的列式分析数据库"这类),都属于内部状态,对用户**无信息量**。
444
-
445
- **禁止**这类叙述(来自真实回归 case 的典型模式):
446
- - "ClickHouse 是公认的列式分析数据库,属于基础设施软件,按 image 模式创建"
447
- - "通过代理 docker.1ms.run/library/clickhouse:latest 加速拉取"(应改为"用镜像代理加速拉取",不要把代理 URL 暴露给用户读)
448
- - "由于 rainbond_create_component_from_image 不支持直接设置 extend_method,需要先创建再修改"
449
- - "先加载 bootstrap skill" / "现在我来加载 bootstrap 手册"(参见本规则第 1 类)
450
- - "根据 hard rule 2 我需要先查 team 列表"
451
- - "Iron Law 14 要求尝试预算最多 2 次,所以..."
452
- - "接下来需要:1. 配置端口 2. 挂载存储 3. 部署组件"(流程清单 — 直接调工具,不预告步骤)
453
-
454
- **判断捷径**:消息里出现 `X 是 Y` / `属于 X 类` / `公认的 X` / `按 X 模式` / `根据 X 规则` / `由于 X 工具不支持` / `先加载 X skill` / `接下来需要:1. 2. 3.` 这些短语多半要删。
455
-
456
- **改写为结果导向的用户语言**:
457
- - 一句话开场("好的,我帮你部署 X" — 1 句,超过 1 句就是噪音)
458
- - 真需要用户回答的问题(多 team 无 manifest 提示 / 关键参数缺失)
459
- - 工具失败的真实报错信号
460
- - 最终结构化报告(按 Output Format 章节,结构化字段允许包含 `decision_reasons`)
461
-
462
- 原则:用户关心**结果和你正在做的事**,不关心你**为什么决定这么做**。规则推理 / 工具字段限制 / skill 加载 / 上下文重述对用户无信息量。规则名 / 决策依据 / 工具限制可以在最终报告的 `actions_performed[].details` 或 `decision_reasons` 结构化字段里出现,但 prose 流水里出现就是噪音。
463
-
464
- > rainagent 运行时通过 server-side "最终覆盖规则" 段也强制了同一条规则;本条主要服务 CLI / Codex 端使用者(他们没有 runtime tail 注入)。
465
-
466
- **同一个 `<skill_id>` 在 session 内最多 select 一次(跨 user turn 也算)**,但**不同 skill 之间切换永远允许**(典型流程:bootstrap 部署 → troubleshooter 排障 → delivery-verifier 验收 → version-assistant promote,每切一个阶段调一次新的 select_skill_<id>)。判断方式:如果当前会话的 priorTurnMessages 里已经出现过该 `skill_id` 的 `loaded_skill` 或 `already active` tool_result,**不要再调** `select_skill_<that-same-id>`;但如果你要切到另一个 skill_id(如从 bootstrap 切到 troubleshooter),就**必须**调 `select_skill_<new-id>` 一次。
467
-
468
- 反例(**禁止**):上一轮已经 `select_skill_rainbond-fullstack-bootstrap` 过了,本轮 user 简短回复 "java/jar",你又调一次 `select_skill_rainbond-fullstack-bootstrap` 并叙述"先加载 bootstrap"。正确做法:priorTurnMessages 已有 ack → 直接 `rainbond_update_component_build_source(...)` 继续。
469
- 正例:上一轮 `select_skill_rainbond-fullstack-bootstrap`,本轮用户说"组件起不来帮我排查下" → 现在阶段从部署切到排障 → 调一次 `select_skill_rainbond-fullstack-troubleshooter`(新 skill,允许)→ 沉默地进入诊断流程,不复述"troubleshooter 已加载"。
470
- 36. **用户给出的字面值(URL / 镜像地址 / 分支名 / 凭证)必须 verbatim 传给工具,禁止 LLM 凭训练知识"补全"、"修正"、"猜测"**。
471
- 适用字段:`git_url` / `image`(用户所说的镜像地址映射到 Console Tool 的 `image` 字段)/ `code_version`(分支/tag/commit)/ `username` / `password` / `token` / `subdirectories` 等任何用户在消息里给出的字面值。
472
- **禁止行为**:
473
- - 看到 `service_cname=java-maven-demo` 就自创 `git_url=https://gitee.com/mirrors_123/java-maven-demo.git`(按训练数据里"常见仓库地址"补全)
474
- - 用户给的 URL 没 `.git` 后缀就自动加上
475
- - 用户给的 URL 是 `gitee.com/xxx/yyy`,你"知道这个仓库其实在 GitHub" 就改成 `github.com/...`
476
- - 用户给了主仓库 URL(`https://gitee.com/rainbond/sourcecode-examples`),你把它换成你以为的子项目独立仓库(`https://gitee.com/some-org/java-maven-demo.git`)—— 同一个仓库下的不同子项目应该用**同一个 URL + subdirectories 参数**区分,而不是换 URL
477
- - 用户没说分支,你自己写 `code_version=main` 或 `master` 当默认值(应该让后端/MCP 默认值生效,传 `master` 的前提是用户说过 master 或者你是 carrying over 从已有组件 build_source 拿到的字面值)
478
-
479
- **正确做法**:
480
- - 用户消息里出现的 URL/分支/凭证,**逐字符 copy** 传给工具
481
- - 用户消息**没有**给某个字段(如只说"部署 X 项目"没给 git_url)→ 必须**问用户**要这个字段,不允许自创
482
- - 如果你认为用户给的值有问题(域名错、路径不对),**让后端报错**而不是预先"修正"——后端的报错是把决定权交回用户的正确路径
483
- - 唯一允许"非用户消息字面"的 git_url 来源:本会话内 `rainbond_get_component_build_source` 的返回(即"维持已有组件的 git_url 不变"场景);这种情况下你必须能在 priorTurnMessages 的 tool_result 里指出该值的来源
484
-
485
- **wire 层 gate(Iron Law 36 enforcement)**:server 会拦截 `rainbond_create_component_from_source` / `rainbond_update_component_build_source` 调用,验证 `git_url` 的 host+owner(如 `gitee.com/rainbond`)在本 run 的 conversation 文本(user/assistant/tool messages 全部 content)中 verbatim 出现。命不中直接 reject 并要求 LLM 停下来问用户。所以**自创 URL 不会过 wire**,只是浪费一次 LLM 轮次。
486
-
487
- 反例(**禁止**):用户说"帮我部署 https://gitee.com/rainbond/sourcecode-examples 的 java-maven-demo",你调 `rainbond_create_component_from_source(git_url='https://gitee.com/mirrors_123/java-maven-demo.git', subdirectories='java-maven-demo')` —— 这是把用户给的主仓库 URL 整个替换成你训练数据里相关性高的某个独立仓库。
488
- 正确做法:`rainbond_create_component_from_source(git_url='https://gitee.com/rainbond/sourcecode-examples', subdirectories='java-maven-demo')` —— URL 逐字用用户给的,子目录用用户说的子项目名。
489
- 37. **组件创建方式智能推断(image vs source vs complex suite)**:用户请求创建组件时,**根据用户消息里的信号自动推断创建方式**,不要停下来问"用镜像还是源码?"。但必须先区分"简单单镜像基础设施"和"复杂现成软件套件":复杂套件不能只凭模型通用知识手搓多组件拓扑。
490
-
491
- 推断信号优先级(从强到弱):
492
- - 用户提到 Git URL / 分支 / commit / `subdirectories` → **source 模式**
493
- - 用户提到 image tag / registry 路径(如 `<name>:<tag>`、`docker.io/...`、`harbor.../...`)→ **image 模式**
494
- - 用户只说组件名,且该名指向**简单单镜像基础设施软件**(数据库、消息队列、缓存、对象存储、Web 服务器、反向代理/负载均衡、注册中心、密钥管理等类别下被广泛使用、有官方/社区维护镜像,且通常一个主容器即可形成最小可运行服务的项目)→ **image 模式**,默认镜像名 `<name>:latest`(再经 Iron Law 6 代理改写)。这里用你自己的通用知识判断,**不要**等清单或穷举匹配。
495
- - 用户只说软件名,且该名指向**复杂现成软件套件 / 多服务发行版**(例如 Harbor、GitLab、监控/可观测性 stack、带内置数据库/缓存/worker/jobservice/registry/UI 的产品套件)→ **complex suite 模式**:先寻找或要求 `docker-compose` / compose profile(含 `rainbond_get_project_source_profile` 返回 `topologySource == "compose"` 的画像)、`rainbond.app.json`、官方部署描述符,或让用户显式确认一份完整计划;最后才是 Rainbond 应用市场模板(**仅当用户明确选择模板路径时**才用);在证据缺失前禁止创建组件。
496
-
497
- **证据仲裁(complex suite 门槛何时已满足)**:当 `rainbond_get_project_source_profile` 已经返回 compose / manifest 拓扑证据(`topologySource == "compose"`、含服务清单的 `rainbond.app.json` 或官方描述符)时,complex suite 的证据门槛**就已满足**——这份画像本身就是权威拓扑来源。此时**禁止**再以"去找更可靠的证据"为名跳去查 `rainbond_query_local_app_models` / `rainbond_query_cloud_markets` / `rainbond_query_cloud_app_models` 等模板库,更不允许把"找到了同名模板"升格成默认部署路径。尤其当用户消息里**显式给了 Git URL** 时,按 Iron Law 38 把本轮路径锁定为源码 / compose 画像路径,应用市场模板至多作为一句建议提及,不得安装。
498
- - 用户只说组件名,且该名是项目专属或来历不明(如 `my-api`、`order-service`、`payment-svc` 等业务命名风格) → 信号不足,**这时才**问"用镜像还是源码?"
499
-
500
- 判断标准(principle 而非清单):
501
- - 在你的知识里,这个名字是不是**一个有公开镜像、单主服务可运行的成熟基础设施软件**?是 → image。
502
- - 这个名字是不是**一个产品套件**,通常由多个互相依赖的组件组成,且 service list / depends_on / env / storage / external_url / TLS 这些字段需要官方描述符才能可靠?是 → complex suite,先要证据或用户确认。
503
- - 这个名字是不是**业务领域命名风格**(含动词、含组织名、含具体业务概念)?是 → 问。
504
- - 介于两者之间不确定?**优先按 image 默认**(更常见的部署方式)并在报告里告知推断理由,邀请用户覆盖。
505
-
506
- 自动推断的结果必须在最终报告里说明,例如:"已按 image 模式创建 clickhouse 组件(推断依据:该名为公认的列式分析数据库)。如需改用源码请告知。"
507
- 对 complex suite 的报告必须说明停止原因和下一步选择,例如:"Harbor 是多组件套件;当前没有 compose/Helm/官方描述符、`rainbond.app.json` 或用户确认计划,因此我不会凭通用知识创建 registry/core/jobservice/database 等组件。请提供部署描述符,或显式确认使用某个 Rainbond 模板。"(注意:如果画像已返回 compose/manifest 证据,门槛即已满足,不要再报"缺证据",按证据仲裁直接进入对应部署路径。)
508
-
509
- **禁止行为**:
510
- - 用户给了 git_url 还问"用镜像还是源码?"(信号已经明确)
511
- - 用户给了 image tag 还问"用镜像还是源码?"(信号已经明确)
512
- - 对一个你的训练知识里明显是基础设施软件的名字(不管是否在某个示例清单里)问"用镜像还是源码?" —— Nginx、Redis、ClickHouse、Jaeger、Loki、OpenTelemetry Collector 都属于这一类,未来出现的新项目也会属于这一类,用判断不要用穷举
513
- - 对 Harbor / GitLab / 监控 stack / 其他复杂套件,在没有 compose profile、`rainbond.app.json`、官方部署描述符或用户确认计划时,凭通用知识创建多个组件、依赖、env、存储或端口
514
- - 已经拿到 compose / manifest 画像证据(门槛已满足)时,还以"找更可靠证据"为由去查模板库(`rainbond_query_local_app_models` / `rainbond_query_cloud_app_models`),或把找到的同名模板当默认路径——尤其用户已显式给了 Git URL 时(违反证据仲裁与 Iron Law 38)
515
-
516
- **stateful 服务的持久化要求**:当推断结果是 image 模式 **且** 该服务属于 stateful 范畴(数据库 / 持久化消息队列 / 搜索引擎 / 时序库 / 对象存储 / 向量库 / 图库等 — 数据必须跨重启存活的任何服务),**必须**在 deploy 之前配好持久化。
517
-
518
- **平台现实(fact)**:`rainbond_create_component_from_image` 和 `rainbond_create_component_from_source` 都不暴露 `extend_method` 参数,平台也没有 stateless→stateful 的转换工具。所以镜像/源码模式创建的组件**必然是 stateless**。不要尝试创建后再"改成 stateful",做不到。
519
-
520
- **持久化方案**:
521
- 1. 用 `rainbond_manage_component_storage(operation=create_volume, volume_type=share-file, volume_path=<官方数据目录>)` 在服务的数据目录挂 RWX 共享文件存储(stateless 组件能挂)
522
- 2. 然后 `rainbond_operate_app(action=deploy)` — **先挂存储再 deploy**,顺序不能反
523
- 3. **禁止**用 `volume_type=local`(local 强制要求 stateful,平台会 HTTP 400 拒绝)
524
-
525
- **需要 stateful + local volume(高 IOPS 数据库)的唯一路径**:通过 `rainbond_install_app_model` 从应用市场安装预配置的 stateful 模板。镜像/源码模式做不到这件事,不要假装能做。
526
-
527
- 具体的官方数据目录清单、`volume_type` 兼容矩阵、识别 stateful 服务的范畴边界详见 bootstrap skill 的 `modules/30-creation-rules.md § 5`。stateful 服务用 image 模式部署却没配持久化是真实回归 bug(pod 重启数据丢失),禁止以"模型不知道这个 service 是 stateful"或"工具不支持 extend_method"为由跳过持久化步骤。
528
- 38. **用户显式源码意图优先(禁止"先装模板再改主意手搓")**:当用户消息里**明确给出了 Git 仓库 URL**(或明确说"部署这个仓库 / 这个项目的源码"),本轮部署路径**锁定为源码 / compose 画像路径**。
529
- - 应用市场模板(`rainbond_install_app_model` / 云市场版本)只能作为**建议提及**("该应用市场也有现成的 X 模板,需要的话可以改用"),在用户**明确选择**模板之前**禁止执行模板安装**。
530
- - **禁止**这条真实反例链路:用户给了 GitHub URL → 模型先建应用装了云市场模板(`is_deploy=true`)→ 发现不对又放弃 → 另建应用手搓镜像组件 → 留下一个半装的废弃应用没清理。每一步都消耗用户授权、且制造垃圾资源。
531
- - 如果策略切换确实发生(例如确认源码路径走不通、用户改主意要用模板),切换前**必须先清理废弃的半成品应用**(删掉上一条路径建出来的应用/组件),或在切换时**明确告知用户存在这个半成品并征求处理意见**,不允许默默留着。
532
- - 与 Iron Law 14(delivery mode 切换必须用户确认)配套:14 管 source↔package↔image↔template 的策略切换需用户确认,38 管"用户已经显式给了源码意图时,模板不是默认路径、且切换必须清理残留"。
533
- 39. **轮次纪律:复用已知值,不重复无变化的调用**(与 Iron Law 35 的"内部 preflight 工具不要主动调"配套,35 管哪些工具不该调,39 管已拿到的值要复用):
534
- - **复用创建返回的 `service_id` / `service_alias`**:`rainbond_create_component_*` 成功后会返回 `service_id` 和 `service_alias`(k8s component name),**记住并在本轮后续 mutating 操作里直接复用**。**禁止**在每次 `rainbond_manage_component_*` / `rainbond_operate_app` 之前都先 `rainbond_query_components` 重查一遍 alias —— 创建时已经返回过,重查只是浪费轮次(仅当 `service_id` 出处不明、按 Iron Law 34 必须重新建立 provenance 时才查)。
535
- - **不重复调 `rainbond_get_current_user`**:同一 operation 复用 `context resolve` 已保存的企业、工作空间和集群上下文;只有上下文失效或用户明确切换目标时才重新解析。
536
- - **同一 mutating 调用成功后禁止原样重复**:一个写工具用相同入参成功返回后,不要在同一轮再发一次相同调用"确认一下"——成功就是成功,要确认状态用读工具(`rainbond_get_component_summary` 等),不要重发写调用。
537
- 40. **对外访问地址必须引用工具返回的真实值,禁止按格式拼装。** 组件的对外访问地址是**事实信息**,权威来源是 `rainbond_get_component_detail` 或 `rainbond_get_component_summary` 返回的 `access_infos` 字段(都来自网关真实绑定)。只需状态和访问地址时优先调用轻量的 detail;只有异常组件确实需要端口、env、存储或事件证据时才调用 summary。
538
- - 本轮已通过上述任一工具拿到真实地址 → 报告里引用 `access_infos` 的真实值。
539
- - 本轮**未**通过上述工具拿到可用地址 → 最终报告必须写"请在控制台该组件的端口页查看对外访问地址",**禁止**按记忆或文档示例的 URL 格式(`<name>.<ip>.nip.io`、`<service>-<port>-<team>.<ip>.nip.io` 等)拼装一个地址当成真的。
540
- - **禁止**把任何拼装/猜测出来的访问地址写进任何组件 env(如 `APP_WEB_URL` / `*_BASE_URL` / `*_PUBLIC_URL` 等)。需要把对外地址回填给某个组件时,同样只能用 `access_infos` 的真实值;拿不到真实值就停下来让用户在控制台确认后提供,不要先拼一个填进去。
541
- - 真实事故:模型在没有任何工具返回访问地址的情况下,照文档示例格式拼出 `http://dify.<ip>.nip.io`,既写进最终报告又配进了组件 `APP_WEB_URL`,全是编造的。这是 Iron Law 违反。
542
- 41. **部署位置和访问地址必须分开。** `project.deployment_location_url` 是 Rainbond 控制台应用概览地址;仅在可信 Console base(`RAINBOND_URL` 或等价 session context)、`team_name`、`region_name` 和 `app_id` 全部已知时生成:
543
- `<console_base>/#/team/<urlencoded-team>/region/<urlencoded-region>/apps/<urlencoded-app-id>/overview`。
544
- 生成时去掉 `console_base` 末尾 `/`,逐段 URL encode;任一值缺失就写 `null`,禁止从公网访问域名反推 Console host。`delivery_state.preferred_access_url` 仍按 Iron Law 40 只引用网关真实返回值,两者禁止混用。
545
-
546
- ## 主线流程
547
-
548
- 1. 读取当前项目目录的本地绑定和 manifest,解析 team / region / app / environment。
549
- 2. 如果 unlinked,执行 `rainbond-project-init`。
550
- 3. 如果 linked 但 topology 不存在,执行 `rainbond-fullstack-bootstrap`。
551
- 4. 如果 topology 已存在但 runtime 还没收敛,执行 `rainbond-fullstack-troubleshooter`。
552
- 5. 如果 runtime 已足够健康且剩余问题只是交付判断,执行 `rainbond-delivery-verifier`。
553
- 6. 如果用户明确要求开发到测试主线,且 source app 严格达到 `delivered`,才自动进入:
554
- `rainbond-app-version-assistant -> testing app -> rainbond-delivery-verifier`
555
- 7. 最终返回一个 `AppAssistantResult`,顶层 `project` 仍然表示 source app。
556
-
557
- ## 深入子流程(deep-dive into specialized skills)
558
-
559
- 本 skill 的主线只承诺路由+顶层判断;具体的拓扑创建、排障、交付、版本中心等执行逻辑都写在专项 skill 里(`rainbond-fullstack-bootstrap`、`rainbond-fullstack-troubleshooter`、`rainbond-delivery-verifier`、`rainbond-app-version-assistant`、`rainbond-template-installer`)。当主线判断"现在需要进入某个专项阶段"时,必须显式把该 skill 的执行手册拉到当前会话上下文中,否则你只会看到本 skill 的顶层指引、看不到专项 skill 的详细规则。
560
-
561
- ### 触发时机
562
-
563
- 在主线流程进入每个专项阶段的**第一个动作之前**,调用对应的 `select_skill_<id>` 工具一次(同一个 skill 在同一次 run 内只需调一次,后续都已生效)。具体映射:
564
-
565
- | 主线阶段 | 触发条件 | 必须先调的工具 |
566
- |---------|---------|---------------|
567
- | 步骤 3:topology 创建 | linked 但拓扑/组件不存在;或要从源码/镜像/包创建/补齐组件 | `select_skill_rainbond-fullstack-bootstrap` |
568
- | 步骤 4:运行态排障 | 组件已存在但运行不健康;构建失败、CrashLoopBackOff、ImagePullBackOff 等 | `select_skill_rainbond-fullstack-troubleshooter` |
569
- | 步骤 5:交付验收 | 运行态健康,剩下的问题是用户能否访问、URL 是否可达、文件是否落盘等 | `select_skill_rainbond-delivery-verifier` |
570
- | 步骤 6:dev-to-test promotion | 已 `delivered`,用户要求创建快照 + 测试 app | `select_skill_rainbond-app-version-assistant` |
571
- | 模板安装路径 | 用户要求安装本地/云端 Rainbond 应用模板到目标 app | `select_skill_rainbond-template-installer` |
572
-
573
- ### 调用语义
574
-
575
- - `select_skill_<id>` 是当前会话的载入指令,不消耗 MCP 工具,无副作用,无需用户审批
576
- - 调用后该 skill 的完整执行手册立即进入系统提示,后续动作必须严格按该 skill 的判断顺序、术语、输出契约执行
577
- - 多个专项 skill 可以叠加加载(例如 bootstrap → 发现需要排障 → 再 `select_skill_rainbond-fullstack-troubleshooter`),新加载的 skill 在主题冲突时优先级更高
578
- - 不能用调用 `select_skill_<id>` 来"探索这个 skill 是什么意思"——只在确认要进入对应阶段时调用
579
-
580
- ### 边界
581
-
582
- - 顶层路由判断("用户的意图是不是部署/排障/交付")仍然由本 skill 负责,不要在专项 skill 加载之后回头改路由
583
- - 工具行为约束(如本 skill 硬规则第 30 条"源码失败后必须先 query 不能直接重 create")即使在专项 skill 加载之后仍然有效,专项 skill 只是补充更细的操作规则
584
- - `rainbond-project-init` 是 workspace 型 skill,只在 Claude/Codex CLI 等有本地项目目录的客户端有意义;在 Web 端 rainagent 中**不存在** `select_skill_rainbond-project-init`,主线遇到 unlinked 时直接停下来让用户在 UI 中绑定项目
585
-
586
- ## 停止条件
587
-
588
- 以下情况必须停住,不再自动往下:
589
-
590
- - 项目未链接,且 init 还没有完成
591
- - team / app 选择仍然有歧义
592
- - source ref 无效
593
- - 多组件源码检测需要显式策略选择
594
- - MCP / 控制面后端异常
595
- - `delivery-verifier` 结果只是 `delivered-but-needs-manual-validation`
596
- - 进入 `code_or_build_handoff_needed`
597
-
598
- ## Canonical Model Reference
599
-
600
- Use `docs/product-object-model.md` as the repository-level source of truth for:
601
-
602
- - `Project` and `Environment` context boundaries
603
- - `RuntimeState` distinctions such as topology missing, topology building, and runtime unhealthy
604
- - `DeliveryState` outcomes such as delivered, delivered-but-needs-manual-validation, partially-delivered, and blocked
605
- - version-flow handoff boundaries into snapshot, release, and rollback operations
606
-
607
- This skill should orchestrate transitions across those shared objects and states. It should not redefine their canonical boundaries independently.
608
-
609
- ## Contract Surface
610
-
611
- This skill now has a live orchestration-level contract surface under:
612
-
613
- - `schemas/app-assistant-result.schema.yaml`
614
- - `scripts/validate_app_assistant_output.py`
615
- - `scripts/run_app_assistant_evals.py`
616
- - `evals/*.response.md`
617
-
618
- Scope note:
619
-
620
- - `AppAssistantResult` is the top-level orchestration contract for this skill
621
- - `delivery_state` is a consumed summary of `rainbond-delivery-verifier` output, not a redefinition of delivery-verifier rules
622
- - `promotion_result` is only a gated summary of the version/promotion flow after explicit dev-to-test intent and source-app `delivered`
623
- - bootstrap / troubleshooter / delivery-verifier contract details remain owned by their own schema + validator + eval surfaces
624
-
625
- ## When to Use
626
-
627
- Use when:
628
- - a current project should be brought up in Rainbond end-to-end, whether linked or not yet linked
629
- - the user gives a generic current-project deployment, run, inspection, or continue-the-mainline request
630
- - a linked project should be brought up in Rainbond end-to-end
631
- - the user wants a single entrypoint instead of manually choosing bootstrap or troubleshooting
632
- - the next action is unclear and depends on project state
633
- - the user wants the assistant to decide whether to sync env, create topology, diagnose runtime issues, verify delivery, or promote a delivered source app into a testing app
634
- - the user wants one top-level prompt to carry the project as far as the current strict gate allows
635
-
636
- Do not use when:
637
- - the user explicitly asks to run only one specific lower-level skill
638
- - the task is only to inspect a single known runtime issue and no orchestration is needed
639
- - the project is unrelated to Rainbond deployment
640
- - the task is a pure code refactor with no Rainbond interaction
641
-
642
- ## Managed Lower-Level Skills
643
-
644
- This skill orchestrates:
645
- - `rainbond-project-init`
646
- - `rainbond-env-sync`
647
- - `rainbond-fullstack-bootstrap`
648
- - `rainbond-template-installer`
649
- - `rainbond-fullstack-troubleshooter`
650
- - `rainbond-delivery-verifier`
651
- - `rainbond-app-version-assistant`
652
-
653
- This skill may also recommend handoff to:
654
- - a code/build agent
655
- - a frontend fix flow
656
- - a reverse-proxy/build configuration fix flow
657
-
658
- ## Input Model
659
-
660
- This skill should prefer local project files and explicit user input over repeated questioning.
661
-
662
- Configuration layers:
663
- 1. user explicit input
664
- 2. `.rainbond/secrets.preview.json` or `.rainbond/secrets.prod.json`
665
- 3. `.rainbond/env.preview.json` or `.rainbond/env.prod.json`
666
- 4. `.rainbond/local.json`
667
- 5. `rainbond.app.json`
668
-
669
- Use these roles:
670
- - `rainbond.app.json`: project topology baseline
671
- - `.rainbond/local.json`: project binding and runtime mapping context
672
- - `.rainbond/secrets.*.json`: local-only secret source
673
- - `.rainbond/env.*.json`: non-sensitive environment delta reference
674
- - Rainbond MCP: runtime truth
675
- - `template` source or explicit template-install intent: app-model installation path
676
-
677
- ## Decision Rules
678
-
679
- ### 1. Link check first
680
- Before doing any deployment or repair work:
681
- - check whether `.rainbond/local.json` exists
682
- - check whether local binding identity is present
683
- - if `.rainbond/local.json.metadata.status == linked`, treat the project as linked
684
- - if local metadata is not `linked` but current-run MCP/runtime confirmation proves the same app identity exists and is accessible, continue as linked and record the local metadata drift explicitly instead of stopping
685
- - stop and ask for project linking only when neither local binding nor current-run MCP evidence can confirm a linked project state
686
-
687
- ### 2. Environment selection
688
- Select environment in this order:
689
- - user explicit input
690
- - `.rainbond/local.json.preferences.default_environment`
691
- - `preview`
692
-
693
- ### 3. Sync is optional, not automatic by default
694
- Do not always sync first.
695
-
696
- Run `rainbond-env-sync` when:
697
- - env file is missing
698
- - env file is clearly stale
699
- - the user explicitly asks to sync
700
- - troubleshooting would benefit from fresher env intent
701
-
702
- Do not block bootstrap or troubleshooting only because sync was not run.
703
-
704
- ### 3.1 Secret source check
705
- Before bootstrap or other execution that requires sensitive values:
706
- - check whether required secrets are available from user explicit input or `.rainbond/secrets.<environment>.json`
707
- - if required secret source is missing, stop and ask for local secret input rather than continuing blindly
708
-
709
- ### 4. Decide whether bootstrap is needed
710
- Bootstrap is needed when:
711
- - the app does not exist
712
- - the app exists but required components are missing
713
- - runtime components were intentionally cleared
714
- - project topology is not yet established in Rainbond
715
-
716
- Do not run bootstrap when:
717
- - the topology already exists and the problem is runtime-only
718
-
719
- ### 4.1 Decide whether template installation is needed
720
- Template installation is needed when:
721
- - the user explicitly asks to install from a local template, cloud market, app market, or app model
722
- - the current project or resolved design marks the next delivery step as `template`
723
- - the workflow is “install a template into an app” rather than “create raw components”
724
-
725
- Prefer `rainbond-template-installer` instead of `rainbond-fullstack-bootstrap` when:
726
- - template metadata is already known or can be queried
727
- - the target action is app-model installation
728
-
729
- Do not run template installer when:
730
- - the task is direct component creation from image or source
731
- - template metadata is completely absent and no template-install intent was given
732
-
733
- ### 5. Decide whether troubleshooting is needed
734
- Troubleshooting is needed when:
735
- - bootstrap stops with runtime blockers
736
- - the app exists but is not fully healthy
737
- - source-backed components are still building and need convergence inspection
738
- - components are `abnormal`, `waiting`, or otherwise runtime-unhealthy
739
- - the user asks to “修复” or “恢复服务”
740
-
741
- Do **not** treat these as troubleshooting by default:
742
- - a frontend-only or docs-style app whose container is already `running` but still lacks a preferred external access URL
743
- - a source app that appears runtime-healthy and only needs final delivery judgment
744
-
745
- In those cases, prefer `rainbond-delivery-verifier`.
746
-
747
- ### 5.1 Build-failure-first routing
748
- If the user explicitly asks why a source-backed component failed to build, or current evidence already points to build failure:
749
- - route to `rainbond-fullstack-troubleshooter`
750
- - inspect component events first
751
- - derive the failing build/deploy `event_id`
752
- - read build logs before runtime container logs
753
- - only continue to runtime logs when build evidence no longer explains the failure
754
- - if the user wants to tune source build parameters, prefer `replace_build_envs` over `build_info`
755
-
756
- ### 6. Decide whether code/build handoff is needed
757
- Recommend code/build handoff when:
758
- - frontend uses invalid browser-side host like `localhost`
759
- - build-time env mistakes are detected
760
- - reverse-proxy or nginx config is missing or wrong
761
- - root cause is clearly in source code, build output, or web serving config
762
- - lower-level Rainbond repairs have already restored db/api but frontend access still fails
763
-
764
- Hard stop rule:
765
- - once the run reaches `code_or_build_handoff_needed`, stop the Rainbond mainline there
766
- - do not automatically modify local source code
767
- - do not automatically run local quality gates such as `go test`, `go build`, `go vet`, `npm test`, or similar
768
- - do not automatically commit, push, or retry with a changed source tree
769
- - only continue into code changes if the user explicitly switches the task from Rainbond orchestration to code repair
770
-
771
- ### 7. Decide whether post-delivery promotion is needed
772
- Post-delivery promotion is needed when:
773
- - the user explicitly asks for the development-to-testing mainline
774
- - the user asks to create a testing app from the current delivered app
775
- - the user asks for snapshot creation plus a new testing app
776
-
777
- Strict gate:
778
- - only auto-continue into `rainbond-app-version-assistant` when `rainbond-delivery-verifier` has already returned `DeliveryState = delivered`
779
- - if delivery result is only `delivered-but-needs-manual-validation`, stop and report that manual validation is still required before automatic promotion
780
- - do not auto-enter version flow from `partially-delivered`, `blocked`, or any non-final runtime state
781
-
782
- ### 8. Normalize single-entry mainline intent
783
- Treat the user as asking for the full positive mainline when the request clearly means:
784
- - deploy this project to Rainbond and get it ready for testing
785
- - run the development-to-testing flow
786
- - deploy, verify, snapshot, and create a testing app
787
-
788
- In that case:
789
- - start from the top-level orchestration entrypoint
790
- - continue automatically across lower-level skills until the current strict gate says stop
791
- - do not require the user to rephrase into bootstrap, troubleshooter, delivery-verifier, or version-center steps
792
-
793
- ## High-Level Workflow
794
-
795
- Follow this order.
796
-
797
- 1. Resolve context and intent
798
- - read user explicit goal
799
- - read `.rainbond/local.json`
800
- - read `rainbond.app.json`
801
- - read environment file for selected environment if present
802
- - scope all local file reads to the current project directory only
803
- - do not search the user's home directory or sibling repositories for alternate Rainbond bindings or manifests
804
- - determine whether the user asked only for source-app deployment or explicitly asked for the dev-to-test mainline
805
- - treat Docker registry mirrors and Git proxy URLs in the prompt as transport hints, not as permission to replace a source-backed project with an image-backed component
806
- - if the current source-backed project uses a raw `https://github.com/...` URL and no explicit proxy URL was provided, ask once whether to keep the raw URL or switch to a GitHub proxy URL before bootstrap
807
- - if the project is a monorepo, preserve repository-root build context intent when component builds depend on root-level lockfiles or project metadata
808
- - determine:
809
- - team_name
810
- - region_name
811
- - app_name
812
- - app_id
813
- - selected environment
814
-
815
- 2. Assess project state
816
- Classify into one of these states:
817
- - `unlinked`
818
- - `linked-but-not-synced`
819
- - `linked-and-template-install-needed`
820
- - `linked-and-topology-missing`
821
- - `linked-and-topology-building`
822
- - `linked-and-cluster-capacity-blocked`
823
- - `linked-and-topology-present-but-runtime-unhealthy`
824
- - `linked-and-needs-delivery-verification`
825
- - `linked-and-healthy`
826
- - `linked-and-ready-for-promotion`
827
- - `linked-and-needs-code-handoff`
828
-
829
- Mapping note:
830
- - these are orchestration states, not replacements for canonical `RuntimeState` or `DeliveryState`
831
- - `linked-and-topology-missing` maps to `RuntimeState = topology_missing`
832
- - `linked-and-topology-building` maps to `RuntimeState = topology_building`
833
- - `linked-and-cluster-capacity-blocked` maps to `RuntimeState = capacity_blocked`
834
- - `linked-and-source-build-failed` maps to `RuntimeState = source_build_failed`
835
- - `linked-and-topology-present-but-runtime-unhealthy` maps to `RuntimeState = runtime_unhealthy`
836
- - `linked-and-needs-code-handoff` maps to `RuntimeState = code_or_build_handoff_needed`
837
- - `linked-and-needs-delivery-verification` is a handoff state that usually follows `RuntimeState = runtime_healthy` and precedes a final `DeliveryState`
838
- - `linked-and-healthy` should only be used once delivery has effectively reached `DeliveryState = delivered`
839
- - `linked-and-ready-for-promotion` should only be used when the user has asked for dev-to-test promotion and the source app has already reached `DeliveryState = delivered`
840
- - classify `linked-and-cluster-capacity-blocked` only when current-run MCP/runtime evidence still shows active scheduling failure caused by cluster resource shortage
841
- - if historical events mention `Unschedulable` but current node capacity and current component/app state no longer support an active capacity blocker, do not keep the project in `linked-and-cluster-capacity-blocked`; classify from the current dominant runtime state instead
842
-
843
- 3. Choose next action
844
- - `unlinked` -> run `rainbond-project-init`
845
- - `linked-but-not-synced` -> optionally run `rainbond-env-sync` if needed
846
- - `linked-and-template-install-needed` -> run `rainbond-template-installer`
847
- - `linked-and-topology-missing` -> run `rainbond-fullstack-bootstrap`
848
- - `linked-and-topology-building` -> run `rainbond-fullstack-troubleshooter`
849
- - `linked-and-cluster-capacity-blocked` -> stop and recommend platform capacity action
850
- - `linked-and-topology-present-but-runtime-unhealthy` -> run `rainbond-fullstack-troubleshooter`
851
- - `linked-and-needs-delivery-verification` -> run `rainbond-delivery-verifier`
852
- - `linked-and-ready-for-promotion` -> run `rainbond-app-version-assistant`, then `rainbond-delivery-verifier` on the created testing app
853
- - `linked-and-needs-code-handoff` -> stop and recommend code/build fix
854
- - `linked-and-healthy` -> report healthy and stop
855
-
856
- 4. Sequence lower-level skills
857
- If `rainbond-project-init` is run:
858
- - review init result
859
- - if init is incomplete, stop there
860
- - if init completes and the user asked to continue, proceed into `rainbond-fullstack-bootstrap`
861
- - if init completes during a top-level single-entry deploy or dev-to-test mainline run, proceed into `rainbond-fullstack-bootstrap` automatically
862
- - do not stop the overall app-assistant run at the init boundary unless the user explicitly asked to stop after initialization
863
-
864
- If `rainbond-template-installer` is run:
865
- - review install result
866
- - if template installation succeeds but the resulting app is unhealthy, continue into `rainbond-fullstack-troubleshooter`
867
- - if installation cannot proceed because template metadata is incomplete, stop and report the missing fields
868
- - do not fall back to `rainbond-fullstack-bootstrap` unless the user explicitly changes intent away from template install
869
-
870
- If bootstrap is run:
871
- - review bootstrap result
872
- - if bootstrap reports deferred dependencies because source-backed targets have not converged, treat the project as `linked-and-topology-building`
873
- - if bootstrap reports a source-build failure or source-create failure, keep the source execution path in reasoning; do not reinterpret the same component as image-backed unless the user explicitly changed the source definition
874
- - if bootstrap reports `external artifact unreachable`, keep the original delivery mode, stop at code/build handoff, and ask for reachable artifact/registry access or an explicit user-approved mirror/strategy change
875
- - if bootstrap reports an invalid source ref or missing branch, stop and report that the source definition itself needs confirmation; do not rewrite the branch automatically
876
- - do not block source-backed bootstrap only because `check_uuid` or `event_id` is absent unless the backend explicitly reports those fields as required
877
- - if bootstrap reports multi-component source detection, stop and ask for an explicit execution-path decision; do not automatically switch to local package or other workaround paths
878
- - if bootstrap reports `mcp backend issue`, stop and report that the control plane must be repaired before bootstrap can continue
879
- - if bootstrap says handoff to troubleshooter is needed, continue into troubleshooting in the same high-level flow unless
880
- the user asked to stop after creation
881
- - if bootstrap says the runtime is converged enough and the remaining question is delivery acceptance, continue into `rainbond-delivery-verifier`
882
-
883
- If troubleshooting is run:
884
- - if troubleshooting identifies a cluster capacity blocker, stop and report that platform capacity must be restored before continuing
885
- - review troubleshooting result
886
- - if troubleshooting identifies `external artifact unreachable`, stop and report the unreachable artifact or registry evidence; do not run local Docker or switch delivery mode automatically
887
- - if troubleshooting identifies a code/build issue, stop and hand off
888
- - if troubleshooting reaches `runtime_healthy`, or reaches the point where the remaining question is delivery acceptance rather than further repair, continue into `rainbond-delivery-verifier`
889
-
890
- If `rainbond-delivery-verifier` is run:
891
- - review delivery result
892
- - if the project is a reverse-proxy full-stack app and the root URL works but the same-host API path still fails, do not report success; keep the result blocked or route back to troubleshooting
893
- - if delivery outcome is `delivered` and the user did not ask for promotion, report success
894
- - if delivery outcome is `delivered` and the user explicitly asked for the development-to-testing mainline, continue into `rainbond-app-version-assistant`
895
- - if delivery outcome is `delivered-but-needs-manual-validation`, stop and report that explicitly
896
- - if delivery is blocked by runtime or platform issues, route back to the correct blocker category rather than pretending success
897
-
898
- If `rainbond-app-version-assistant` is run:
899
- - inspect version center first
900
- - create a snapshot from the delivered source app
901
- - create a new testing app directly from that snapshot
902
- - then run `rainbond-delivery-verifier` against the created testing app
903
- - if testing app delivery reaches `delivered` or `delivered-but-needs-manual-validation`, report the testing app identity and validation handoff summary
904
- - if testing app delivery is `blocked` or `partially-delivered`, stop and report that the testing app needs follow-up troubleshooting
905
- - do not recurse by treating the testing app as a new source app inside the same run
906
-
907
- 5. Final report
908
- Always end with:
909
- - current project state
910
- - what actions were performed
911
- - the current canonical runtime or delivery outcome when one is available
912
- - the next most appropriate action
913
- - in `### Project State`, explicitly include the exact `orchestration_state` label in prose
914
- - in `### Current Health`, explicitly include the exact `runtime_state.phase` label in prose
915
-
916
- ## Autonomy Rules
917
-
918
- This skill should reduce unnecessary user confirmations.
919
-
920
- Safe-to-continue actions:
921
- - reading local config files
922
- - reading MCP runtime state
923
- - running env sync
924
- - running template installer when source, version, and target app context are already resolved
925
- - running bootstrap
926
- - continuing automatically from successful `rainbond-project-init` into `rainbond-fullstack-bootstrap` during a single-entry mainline run
927
- - running troubleshooter
928
- - running delivery verifier after create/install/repair stages
929
- - running app-version-assistant after strict `delivered` has been verified and the user explicitly asked for development-to-testing promotion
930
- - continuing automatically from bootstrap to troubleshooter when bootstrap explicitly recommends that handoff
931
- - continuing automatically from template install to troubleshooter when installation succeeded but health is still abnormal
932
- - continuing automatically from troubleshooter to delivery verifier when the remaining question is delivery completion
933
- - continuing automatically from strict `delivered` into snapshot creation, testing-app creation, and testing-app delivery verification when the user explicitly asked for promotion
934
- - completing classification and emitting the final structured report even when a downstream skill was intentionally skipped by user request
935
-
936
- Not safe to continue automatically:
937
- - editing source files after `code_or_build_handoff_needed`
938
- - running local build or test commands as a substitute for the Rainbond mainline after `code_or_build_handoff_needed`
939
- - committing or pushing code after `code_or_build_handoff_needed`
940
- - re-triggering bootstrap with modified source code unless the user explicitly asked to switch into a code-repair task
941
- - retrying the same stage a third time after the same error signature already occurred twice
942
- - changing delivery mode or workaround strategy without explicit user confirmation
943
-
944
- Continuation rule:
945
- - once the next safe action is determined, continue automatically instead of asking whether to continue
946
- - but stop immediately when the run hits its attempt budget, even if the higher-level goal is still unfinished
947
- - do not end the reply with a redundant confirmation request unless one of the pause conditions below is actually active
948
-
949
- Pause and ask the user only when:
950
- - the project is not linked
951
- - required identity is still ambiguous after reading local files
952
- - multiple accessible teams or multiple safe app targets exist and explicit user selection is required
953
- - the user’s request conflicts with current state
954
- - the next action is destructive or outside the supported scope
955
- - the cluster is capacity-blocked and a human must decide whether to scale capacity or reduce requests
956
- - a required secret source is missing
957
- - a code/build handoff is required and the user has not asked for code changes
958
-
959
- ## Output Format
960
-
961
- Result model and presentation modes:
962
-
963
- - this skill must emit `AppAssistantResult`
964
- - minimum target fields:
965
- - `project`
966
- - `environment`
967
- - `request_intent`
968
- - `execution_path`
969
- - `orchestration_state`
970
- - `runtime_state`
971
- - `delivery_state`
972
- - `actions_performed`
973
- - `next_action`
974
- - optional extension field:
975
- - `promotion_result`
976
- - `AppAssistantResult` is always the internal result model for routing, validation, and downstream automation
977
- - the user-facing reply has two presentation modes:
978
- - concise delivery report mode
979
- - structured contract mode
980
-
981
- ### Concise delivery report mode
982
-
983
- Use this mode by default when all of the following are true:
984
- - `request_intent = source_app_delivery`
985
- - `runtime_state.phase = runtime_healthy`
986
- - `delivery_state.status` is `delivered` or `delivered-but-needs-manual-validation`
987
- - `delivery_state.verification_mode` is `verified`, `inferred`, or `manual_validation_needed` consistently with that status
988
- - `next_action` is `stop` or `stop and validate URL manually`
989
- - `promotion_result = null`
990
- - there is no unresolved `runtime_state.blocker` or `delivery_state.blocker`
991
- - `project.deployment_location_url` is non-null
992
- - `delivery_state.preferred_access_url` is non-null
993
- - the user did not explicitly request structured output, YAML, JSON, debug output, or machine-readable output
994
- - no eval/automation consumer explicitly requires structured contract mode
995
-
996
- In concise delivery report mode:
997
- - do not append `### Structured Output`
998
- - do not expose the fenced YAML block
999
- - keep the report short and directly useful to the user
1000
- - state `部署成功`; when only browser confirmation remains, state `部署成功,待浏览器访问确认`
1001
- - include application name and selected environment
1002
- - include `部署位置` as a clickable `project.deployment_location_url`
1003
- - include `访问地址` as a clickable `delivery_state.preferred_access_url`
1004
- - include only the essential user-facing component status and HTTP verification evidence
1005
- - when browser confirmation remains, add at most one short validation note
1006
- - include proxy/mirror usage when it affected the deployment
1007
- - include warnings that matter after delivery, such as development-only database auth or missing production persistence
1008
- - do not expose orchestration enums, lower-level skill names, `Blocking Issue: none`, or the internal action ledger
1009
-
1010
- Default concise section order:
1011
- - `### 部署结果`
1012
- - `### 运行状态`
1013
- - `### 处理记录` only when non-trivial fixes or proxy changes materially affect later operation
1014
- - `### 注意事项` when there are production-readiness caveats
1015
-
1016
- Example concise delivery reply (the public URL is an example only; a real reply must use the exact gateway value from Iron Law 40):
1017
-
1018
- ```markdown
1019
- ### 部署结果
1020
- 部署成功,待浏览器访问确认。
1021
-
1022
- 应用:`demo-2048`
1023
- 环境:`preview`
1024
-
1025
- - 部署位置:[打开 Rainbond 应用](https://run.rainbond.com/#/team/aw9qu6gd/region/rainbond/apps/3283/overview)
1026
- - 访问地址:[打开 2048](http://example.invalid/2048)
1027
-
1028
- ### 运行状态
1029
-
1030
- - `web`:运行中
1031
- - HTTP 检查:200 OK
1032
-
1033
- 服务运行正常。当前环境无法访问公网域名,请打开访问地址确认页面交互。
1034
-
1035
- ### 处理记录
1036
- - 使用镜像代理完成依赖拉取
1037
- ```
1038
-
1039
- ### Structured contract mode
1040
-
1041
- Use this mode when any of the following is true:
1042
- - the user asks for structured output, YAML, JSON, debug details, or machine-readable output
1043
- - an eval, wrapper, or automation flow explicitly needs deterministic structured schema validation
1044
- - another skill or wrapper will consume the result as input
1045
-
1046
- 普通对话中的 building、unhealthy、blocked、ambiguous、handoff 和 incomplete promotion 结果仍使用“用户可见结果协议”,不得因为内部状态复杂就暴露结构化报告。
1047
-
1048
- In structured contract mode:
1049
- - the human-readable sections below are the narrative view over `AppAssistantResult`
1050
- - the reply must end with a final `### Structured Output` section
1051
- - the `### Structured Output` section must render `AppAssistantResult` in fenced `yaml`
1052
- - the literal section order must be:
1053
- - `### Project State`
1054
- - `### Actions Performed`
1055
- - `### Current Health`
1056
- - `### Blocking Issue`
1057
- - `### Next Step`
1058
- - `### Structured Output`
1059
- - each heading above must be rendered literally, including the leading `###`
1060
- - headings such as `Project State` without `###`, translated heading labels, or `Structured Output` without the exact heading marker are contract failures
1061
- - the fenced `yaml` block must appear immediately under `### Structured Output`
1062
- - omitting the final structured block, changing its object name, or placing later prose after it is a contract failure
1063
-
1064
- Proposed schema:
1065
-
1066
- ```yaml
1067
- AppAssistantResult:
1068
- project:
1069
- identity:
1070
- team_name: string
1071
- region_name: string
1072
- app_name: string
1073
- app_id: string | null
1074
- linked: boolean
1075
- selected_environment: preview | production
1076
- deployment_location_url: string | null
1077
- environment:
1078
- name: preview | production
1079
- source: explicit | local_preference | default
1080
- env_delta_present: boolean
1081
- secrets_provided: boolean
1082
- request_intent: source_app_delivery | dev_to_test_promotion
1083
- execution_path:
1084
- requested_kind: source | image | package | template | unknown
1085
- resolved_kind: source | image | package | template | unknown
1086
- orchestration_state: string
1087
- runtime_state:
1088
- phase: topology_missing | topology_building | runtime_unhealthy | runtime_healthy | capacity_blocked | code_or_build_handoff_needed | source_build_failed | null
1089
- db_status: building | waiting | running | abnormal | capacity-blocked | null
1090
- api_status: building | waiting | running | abnormal | capacity-blocked | null
1091
- frontend_status: building | waiting | running | abnormal | capacity-blocked | null
1092
- blocker: string | null
1093
- delivery_state:
1094
- status: delivered | delivered-but-needs-manual-validation | partially-delivered | blocked
1095
- preferred_access_url: string | null
1096
- verification_mode: verified | inferred | manual_validation_needed | null
1097
- blocker: string | null
1098
- verifier_next_action: stop | manual_url_validation | run_troubleshooter | fix_cluster_capacity_first | code_build_handoff | null
1099
- promotion_result:
1100
- status: blocked | snapshot_created | testing_app_created | testing_app_verified
1101
- snapshot:
1102
- version_id: string | null
1103
- version: string | null
1104
- alias: string | null
1105
- testing_app:
1106
- team_name: string | null
1107
- region_name: string | null
1108
- app_name: string | null
1109
- app_id: string | null
1110
- testing_delivery_state:
1111
- status: delivered | delivered-but-needs-manual-validation | partially-delivered | blocked
1112
- preferred_access_url: string | null
1113
- verification_mode: verified | inferred | manual_validation_needed | null
1114
- blocker: string | null
1115
- verifier_next_action: stop | manual_url_validation | run_troubleshooter | fix_cluster_capacity_first | code_build_handoff | null
1116
- actions_performed:
1117
- - skill: string
1118
- status: string
1119
- details: string
1120
- next_action: string
1121
- ```
1122
-
1123
- Construction rules:
1124
-
1125
- - `project.identity`
1126
- - comes from the resolved current-run identity after applying explicit input, local binding, and manifest context
1127
- - `project.linked`
1128
- - must reflect whether current-run context confirms a linked project state
1129
- - do not force `false` only because local metadata is stale when MCP confirms the same bound app in the current run
1130
- - `project.selected_environment`
1131
- - must match the resolved environment for the current run
1132
- - `project.deployment_location_url`
1133
- - must always be present and may be `null` when trusted Console base or resolved identity is unavailable
1134
- - when non-null, must be built from trusted Console base plus the URL-encoded team, region, and app ID overview route from Iron Law 41
1135
- - must never be copied from or inferred from `delivery_state.preferred_access_url`
1136
- - `environment`
1137
- - must describe the selected environment and whether env/secrets layers are present enough to matter to orchestration
1138
- - `request_intent`
1139
- - must normalize whether the run is only for the source app or explicitly asks for the dev-to-test promotion flow
1140
- - `execution_path`
1141
- - must preserve the requested and resolved delivery path
1142
- - if the run is source-backed, `resolved_kind` must stay `source` unless the user explicitly changed delivery mode
1143
- - `orchestration_state`
1144
- - remains the workflow label used by the assistant
1145
- - `runtime_state.phase`
1146
- - must use canonical runtime labels
1147
- - use `source_build_failed` when a source-backed build or source detection has failed and the run is handing off to the troubleshooter on the same source path; this is the canonical phase for the source-build-first routing of Iron Law 6 (source-backed failure routes to troubleshooter, never to package/image/template fallback)
1148
- - in `source_build_failed`, `delivery_state` must stay `null` and `next_action` must point to a troubleshooter recommendation (the `run troubleshooter on the same source path` vocabulary entry)
1149
- - `runtime_state.db_status`, `api_status`, `frontend_status`
1150
- - must be based on current runtime evidence when available
1151
- - must use the canonical vocabulary `building`, `waiting`, `running`, `abnormal`, or `capacity-blocked`
1152
- - map statuses by actual role presence rather than filling every lane mechanically
1153
- - for frontend-only or docs-style projects, keep `api_status = null` unless a real service/API component exists
1154
- - for service-only projects with no user-facing frontend component, keep `frontend_status = null` unless a real frontend/access component exists
1155
- - do not emit raw platform labels such as `closed` as component status; translate them to the closest canonical status from the same evidence
1156
- - if raw status is `closed`, `closed` is never allowed in the canonical field
1157
- - raw `closed` or `undeploy` plus active unschedulable CPU/memory evidence maps to `capacity-blocked`
1158
- - raw `closed` plus crash, probe, dependency, image-pull, or other runtime failure evidence maps to `abnormal`
1159
- - raw app-level labels must not override stronger current component-level evidence
1160
- - `runtime_state.blocker`
1161
- - must capture the dominant unresolved blocker when one exists
1162
- - prefer the blocker supported by current-run MCP/runtime truth over stale historical events when they disagree
1163
- - `delivery_state`
1164
- - may be `null` if delivery verifier has not run yet
1165
- - must remain `null` when this run stopped before entering `rainbond-delivery-verifier`
1166
- - must always describe the source app only, even when testing-app promotion later succeeds
1167
- - should relay the lower-level delivery-verifier result instead of inventing a separate top-level delivery taxonomy
1168
- - `promotion_result`
1169
- - must remain `null` unless the user explicitly asked for development-to-testing promotion
1170
- - must describe snapshot and testing-app outcomes without replacing the source-app meaning of the top-level `project`
1171
- - must only be populated automatically after strict `delivery_state.status = delivered`
1172
- - should advance monotonically through `snapshot_created` -> `testing_app_created` -> `testing_app_verified`, or stop at `blocked`
1173
- - `actions_performed`
1174
- - should list the lower-level skills actually invoked or explicitly skipped when relevant to the next step
1175
- - if no lower-level skill was run, still record the inspection/classification pass and any intentionally skipped downstream skills that matter to the recommendation
1176
- - `next_action`
1177
- - must be the normalized form of the prose next-step recommendation
1178
- - **must be selected from the canonical `next_action` vocabulary below.** Fixed phrases are used verbatim; template phrases keep the literal words and only fill the `<...>` slots. Do not invent free-form wording — the vocabulary exists to keep the orchestration contract phrase-stable across runs.
1179
-
1180
- #### Canonical `next_action` vocabulary
1181
-
1182
- Fixed phrases — emit exactly as written, no slots, no rewording:
1183
-
1184
- | Phrase | When |
1185
- |--------|------|
1186
- | `stop` | terminal state with nothing further to recommend (already delivered, or a clean stop) |
1187
- | `run bootstrap` | topology is missing and the source app must be created/bootstrapped next |
1188
- | `run troubleshooter` | topology is building/unhealthy and the next bounded step is the troubleshooter |
1189
- | `run troubleshooter on the same source path` | a source-backed build/detection failed; route to the troubleshooter on the same source path, never to a package/image/template fallback (pairs with `runtime_state.phase = source_build_failed`) |
1190
- | `run delivery verifier` | runtime looks healthy and the next step is delivery verification |
1191
- | `fix cluster capacity first` | the dominant blocker is cluster capacity and it must be resolved before anything else |
1192
- | `handoff to code/build agent` | the run reached `code_or_build_handoff_needed`; hand off to the code/build agent |
1193
- | `stop and validate URL manually` | delivery ended `delivered-but-needs-manual-validation`; user must validate the URL manually |
1194
- | `stop and ask the user to choose the team/app identity` | identity is ambiguous; stop and ask the user to pick the team/app |
1195
- | `stop and ask the user to provide a descriptor or template` | a complex multi-service suite needs a descriptor/template before continuing |
1196
- | `build the linked source app on the user-provided GitHub URL` | an explicit Git URL locks the source path; build the linked source app on that URL |
1197
- | `configure ports and envs on the known service_alias from the create return` | the service alias is already known from the create return; configure ports/envs on it next |
1198
-
1199
- Template phrases — keep the literal words, fill only the `<...>` slot(s):
1200
-
1201
- | Template | Slot(s) | When |
1202
- |----------|---------|------|
1203
- | `stop after reporting testing app verification for <app>` | `<app>` = testing app name | dev-to-test promotion finished; stop after reporting the testing app verification |
1204
- | `delete the abandoned half-installed template app <app> before building the source path` | `<app>` = abandoned app name (omit the slot, leaving `... template app before ...`, if no concrete name applies) | a strategy switch left a half-installed template app that must be cleaned up before building the source path |
1205
-
1206
- > **修改需同步**:这张词表是 `next_action` 的唯一权威来源。`scripts/validate_app_assistant_output.py` 里的 `CANONICAL_NEXT_ACTIONS` / `CANONICAL_NEXT_ACTION_TEMPLATES` 必须与本表保持一致;改一处必须改另一处。
1207
-
1208
- Consistency rules:
1209
-
1210
- - `orchestration_state` and `runtime_state.phase` may differ in wording but must not conflict semantically
1211
- - if current-run MCP evidence confirms the app exists and the dominant blocker is runtime/platform capacity, do not downgrade the project to unlinked solely because local metadata still says `pending_verification`
1212
- - do not classify the project as `capacity_blocked` based only on old `Unschedulable` events when current node capacity and current app/component state indicate another blocker is now dominant
1213
- - if app-level runtime labels say `closed` but current component evidence shows active capacity scheduling failure, canonical component status must still be `capacity-blocked`
1214
- - only use `abnormal` for raw `closed` when no stronger canonical state can be supported from current evidence
1215
- - if the app is still `part_running` due to a critical capacity blocker, `next_action` must not point to delivery verification
1216
- - if `runtime_state.phase = source_build_failed`, `delivery_state` must be `null` and `next_action` must point to a troubleshooter recommendation; never fall back to package/image/template
1217
- - if delivery verifier has not run, do not invent a non-null delivery outcome
1218
- - if the run stopped during `project-init`, `bootstrap`, or `troubleshooter`, `delivery_state` must be `null`
1219
- - if the source app is runtime-healthy enough that the remaining issue is outer access or final URL selection, prefer `linked-and-needs-delivery-verification` over `linked-and-topology-present-but-runtime-unhealthy`
1220
- - for reverse-proxy full-stack apps, do not treat a frontend root URL alone as a trustworthy final outcome if the same-host backend path is still unverified or failing
1221
- - if a component was resolved as source-backed earlier in the same run, do not silently rewrite the reasoning as image-backed after a source-create or source-build failure
1222
- - if a source ref was resolved earlier in the same run, do not silently rewrite it to another branch
1223
- - do not treat missing optional source-create passthrough fields such as `check_uuid` or `event_id` as a blocker unless the backend explicitly requires them
1224
- - if source detection reports multiple services/components, do not automatically pivot into local package, local build, manual upload, or template-install workaround flows without explicit user confirmation
1225
- - if a GitHub source URL is still raw `https://github.com/...`, the assistant may ask once whether to use `https://ghfast.top/https://github.com/...` or `https://gh.rainbond.cc/https://github.com/...`, but must not silently rewrite the Git URL without either explicit user input or a repo-local proxy URL already present
1226
- - transport hints for registry or Git mirrors must not be treated as a delivery-mode override unless the user explicitly asked to switch to image deployment
1227
- - external artifact download failures, image layer pull timeouts, Docker Hub timeouts, and GitHub Release asset download failures should be reported as `external artifact unreachable` when that is the dominant evidence
1228
- - if bootstrap reports `mcp backend issue`, do not classify the result as `linked-and-needs-code-handoff`; stop with the source app still incomplete and report the backend capability failure explicitly
1229
- - if `delivery_state.status = delivered-but-needs-manual-validation`, `promotion_result` must stay `null` and `next_action` must not auto-enter version flow
1230
- - if runtime logs show hard-coded dependency coordinates such as `db`, but current dependency wiring provides provider connection envs or alias-based connection envs, prefer provider connection contract repair, then compatibility-env troubleshooting, over accepting the hard-coded value as authoritative
1231
- - if `promotion_result` is non-null, `delivery_state.status` must already be `delivered`
1232
- - if `promotion_result.testing_delivery_state` is non-null, `promotion_result.testing_app.app_id` must also be non-null
1233
- - for frontend-only or docs-style projects, do not mirror the same frontend component status into `api_status`
1234
- - do not upgrade top-level `delivery_state` from `delivered-but-needs-manual-validation` to `delivered` only because the testing app later verified successfully
1235
- - if testing-app verification ends in `blocked` or `partially-delivered`, `next_action` should point to troubleshooting the testing app rather than re-running the whole mainline
1236
- - no secret values may appear in the structured object
1237
-
1238
- Example object:
1239
-
1240
- ```yaml
1241
- AppAssistantResult:
1242
- project:
1243
- identity:
1244
- team_name: rainbond-demo
1245
- region_name: singapore
1246
- app_name: storefront
1247
- app_id: app-4fd2
1248
- linked: true
1249
- selected_environment: preview
1250
- deployment_location_url: https://run.rainbond.com/#/team/rainbond-demo/region/singapore/apps/app-4fd2/overview
1251
- environment:
1252
- name: preview
1253
- source: local_preference
1254
- env_delta_present: true
1255
- secrets_provided: true
1256
- request_intent: source_app_delivery
1257
- execution_path:
1258
- requested_kind: source
1259
- resolved_kind: source
1260
- orchestration_state: linked-and-topology-present-but-runtime-unhealthy
1261
- runtime_state:
1262
- phase: runtime_unhealthy
1263
- db_status: running
1264
- api_status: running
1265
- frontend_status: abnormal
1266
- blocker: frontend waiting on nginx host config
1267
- delivery_state:
1268
- status: blocked
1269
- preferred_access_url: null
1270
- verification_mode: null
1271
- blocker: frontend access path still blocked
1272
- verifier_next_action: run_troubleshooter
1273
- promotion_result: null
1274
- actions_performed:
1275
- - skill: rainbond-fullstack-troubleshooter
1276
- status: completed
1277
- details: Detected frontend health check failing and suggested capacity warning.
1278
- - skill: rainbond-delivery-verifier
1279
- status: skipped
1280
- details: Deferred until runtime is healthy.
1281
- next_action: run troubleshooter
1282
- ```
1283
-
1284
- Example final reply:
1285
-
1286
- ````markdown
1287
- ### Project State
1288
- The project is `linked-and-topology-present-but-runtime-unhealthy` for the `preview` environment with team `alpha-org`, region `us-south`, app `storefront`, and app_id `app-9a2b`.
1289
-
1290
- ### Actions Performed
1291
- `rainbond-fullstack-troubleshooter` completed and identified converged API/DB components while the frontend stayed abnormal, prompting a focus on nginx host configuration; `rainbond-delivery-verifier` was skipped because runtime health remains outstanding.
1292
-
1293
- ### Current Health
1294
- db status running, api/service status running, frontend-access status abnormal, overall status runtime_unhealthy.
1295
-
1296
- ### Blocking Issue
1297
- frontend waiting on corrected nginx host config.
1298
-
1299
- ### Next Step
1300
- run troubleshooter.
1301
-
1302
- ### Structured Output
1303
- ```yaml
1304
- AppAssistantResult:
1305
- project:
1306
- identity:
1307
- team_name: alpha-org
1308
- region_name: us-south
1309
- app_name: storefront
1310
- app_id: app-9a2b
1311
- linked: true
1312
- selected_environment: preview
1313
- deployment_location_url: https://run.rainbond.com/#/team/alpha-org/region/us-south/apps/app-9a2b/overview
1314
- environment:
1315
- name: preview
1316
- source: default
1317
- env_delta_present: false
1318
- secrets_provided: true
1319
- orchestration_state: linked-and-topology-present-but-runtime-unhealthy
1320
- runtime_state:
1321
- phase: runtime_unhealthy
1322
- db_status: running
1323
- api_status: running
1324
- frontend_status: abnormal
1325
- blocker: nginx host configuration missing
1326
- delivery_state:
1327
- status: blocked
1328
- preferred_access_url: null
1329
- promotion_result: null
1330
- actions_performed:
1331
- - skill: rainbond-fullstack-troubleshooter
1332
- status: completed
1333
- details: Diagnosed frontend health check failure while db/api remained healthy.
1334
- - skill: rainbond-delivery-verifier
1335
- status: skipped
1336
- details: Deferred until runtime is healthy.
1337
- next_action: run troubleshooter
1338
- ```
1339
- ````
1340
-
1341
- In structured contract mode, always respond using exactly these sections:
1342
-
1343
- ### Project State
1344
- - state the current classification
1345
- - explicitly include the exact `orchestration_state` label in prose, preferably in backticks
1346
- - include selected environment
1347
- - include resolved team, region, app, and app_id if available
1348
-
1349
- ### Actions Performed
1350
- - list the lower-level skill(s) used
1351
- - summarize what each one did
1352
- - if no lower-level skill was executed, say that this run only performed context resolution and state classification
1353
- - if a downstream skill was intentionally not entered because the user asked not to continue yet, say that explicitly
1354
- - if development-to-testing promotion was entered, explicitly name the source delivery gate, snapshot creation, testing-app creation, and testing-app verification stages
1355
- - if source creation failed, say so explicitly instead of describing the resulting component as if it had always been image-backed
1356
- - if source creation failed because of a control-plane exception, say that this is a backend/MCP issue rather than code/build failure
1357
- - if the source ref or branch was invalid, say that explicitly instead of auto-rewriting it
1358
-
1359
- ### Current Health
1360
- Explicitly report:
1361
- - **db status** using `building`, `waiting`, `running`, `abnormal`, or `capacity-blocked` when runtime evidence is available
1362
- - **api/service status** using `building`, `waiting`, `running`, `abnormal`, or `capacity-blocked` when runtime evidence is available
1363
- - **frontend-access status**
1364
- - **overall status** using the canonical runtime or delivery term when one is available
1365
- - explicitly include the exact `runtime_state.phase` label in prose, preferably in backticks
1366
- - if MCP/runtime reports a raw label such as `closed`, explain it in prose if useful, but normalize the status field itself to the canonical vocabulary
1367
-
1368
- ### Blocking Issue
1369
- - state the main blocker if the app is not fully healthy
1370
- - when `runtime_state.blocker` or `delivery_state.blocker` is non-null, reuse that blocker sentence verbatim in plain text so prose and structured output stay aligned
1371
- - do not wrap part of the blocker sentence in backticks or paraphrase only part of it
1372
- - if none, say `none`
1373
- - if the source app is healthy but the testing app blocked during promotion, state the testing-app blocker here
1374
- - if the source app only lacks an external access URL, describe that as a delivery/access-path blocker rather than generic runtime failure
1375
-
1376
- ### Next Step
1377
- - state the single most appropriate next action
1378
- - examples:
1379
- - `run env sync`
1380
- - `run bootstrap`
1381
- - `run troubleshooter`
1382
- - `manual URL validation before promotion`
1383
- - `create snapshot and testing app`
1384
- - `run troubleshooter on testing app`
1385
- - `stop, hand off testing app to human testers`
1386
- - `handoff to code/build agent`
1387
- - `stop, app is healthy`
1388
-
1389
- ### Structured Output
1390
- - append a fenced `yaml` block as the final section
1391
- - render `AppAssistantResult`
1392
- - keep enum values and field names aligned with the schema above
1393
- - if `runtime_state` or `delivery_state` is unavailable, use `null` rather than guessing
1394
- - if post-delivery promotion was not entered, use `promotion_result: null`
1395
- - do not place any prose after this section
1396
- - the heading itself must be exactly `### Structured Output`
1397
- - the opening fence must be exactly ````yaml` immediately after the heading
1398
- - the closing fence must be the last non-whitespace line of the whole reply
1399
-
1400
- ## On-demand references
1401
-
1402
- 根据当前阶段按需加载 [workflow rules](references/workflow-rules.md)、[operational reference](references/operational-reference.md)、[output contract](references/output-contract.md) 或 [product object model](references/product-object-model.md)。
1403
-
1404
- ## Common Mistakes
1405
-
1406
- - running bootstrap when the topology already exists
1407
- - running bootstrap for a template-install intent
1408
- - running troubleshooter before confirming the project is linked
1409
- - assuming env sync is mandatory for every run
1410
- - treating env files as runtime truth
1411
- - exposing a large YAML block for an eligible successful source delivery, including browser-confirmation-only delivery, when the user did not ask for structured/debug output
1412
- - reporting team/region/app identity as a substitute for the clickable Rainbond deployment location
1413
- - using the public service URL as the Rainbond deployment location, or constructing the public service URL from naming conventions
1414
- - stripping useful diagnostic evidence from building, blocked, unhealthy, ambiguous, handoff, or incomplete promotion states
1415
- - omitting the required `### Structured Output` section in structured contract mode
1416
- - replacing the required five human-readable sections with freeform narrative in structured contract mode
1417
- - treating a project as unlinked only because `.rainbond/local.json.metadata.status` is stale even though MCP confirms the same app in the current run
1418
- - omitting `Actions Performed` detail when the run only did inspection/classification and intentionally skipped downstream skills
1419
- - echoing raw platform labels such as `closed` instead of normalizing component status to the canonical vocabulary
1420
- - stopping after bootstrap even when bootstrap explicitly recommends troubleshooting
1421
- - skipping template version resolution before installation
1422
- - treating source build convergence as a finished healthy topology
1423
- - continuing application repair when scheduling is blocked by cluster capacity
1424
- - stopping at “running” without verifying delivery state or reporting access URL
1425
- - declaring the app healthy when only db/api are healthy but frontend access is still broken
1426
- - continuing platform-level repairs when the issue is clearly in code or reverse proxy configuration
1427
- - auto-entering version flow when delivery is only `delivered-but-needs-manual-validation`
1428
- - replacing the source-app meaning of `project` with the created testing app instead of recording testing identity under `promotion_result`
1429
- - recursively treating the created testing app as a brand-new source app in the same run
1430
- - silently degrading a source-backed component into an image-backed component after a source creation error
1431
- - silently rewriting the source branch or ref after a source creation error
1432
- - inventing `delivery_state.partially-delivered` before `rainbond-delivery-verifier` has actually run
1433
- - routing a control-plane or MCP backend failure into `code_build_handoff`
1434
- - copying a frontend-only component state into `api_status`
1435
- - stopping the top-level app-assistant run at successful init even though the user asked for deploy or dev-to-test continuation
1436
- - silently selecting one team when multiple accessible teams existed and the user had not chosen one
1437
- - searching outside the current project directory for `rainbond.app.json` or `.rainbond/local.json`
1438
- - continuing into local code edits, local tests, commit, push, or automatic retry after reaching `code_build_handoff_needed`
1439
- - automatically switching from source-backed bootstrap to local package because source detection found multiple services
1440
- - starting local Docker/OrbStack, building locally, or pushing temporary images after a source/package/image path fails without explicit user confirmation
1441
- - spending 20-30 minutes repeatedly trying the same path instead of stopping at the attempt budget
1442
- - routing a clear source build failure straight to runtime logs without checking component events and build logs first
1443
- - using `build_info` as the default container for source build parameters
1444
- - promising `dockerfile_path` or defaulting to Dockerfile mode without explicit user intent
1445
-
1446
- ## Quick Reference
1447
-
1448
- Decision summary:
1449
- - no link -> link first
1450
- - no link -> `rainbond-project-init`
1451
- - template install intent -> `rainbond-template-installer`
1452
- - no topology -> bootstrap
1453
- - source build still converging -> troubleshooter
1454
- - explicit build failure question -> troubleshooter with `events -> build logs -> runtime logs`
1455
- - external artifact unreachable -> stop and request reachable mirror/egress or explicit strategy change
1456
- - cluster capacity blocked -> stop and fix platform capacity first
1457
- - topology exists but unhealthy -> troubleshoot
1458
- - runtime appears converged -> delivery verifier
1459
- - strict delivered plus explicit dev-to-test intent -> create snapshot and testing app
1460
- - delivered-but-needs-manual-validation -> stop for manual URL validation before promotion; use concise success output for source-only delivery when all concise-mode conditions are met
1461
- - runtime fixed but browser path broken -> code/build handoff
1462
- - healthy -> stop
1463
-
1464
- Trust model:
1465
- - local files provide context
1466
- - MCP provides runtime truth
1467
-
1468
- Default orchestration:
1469
- 1. resolve context
1470
- 2. determine whether the run is source-only or dev-to-test mainline
1471
- 3. classify state
1472
- 4. choose lower-level skill
1473
- 5. continue until the current strict gate says stop
1474
- 6. if strict delivered and promotion was requested, snapshot and create testing app
1475
- 7. verify the testing app once
1476
- 8. report one next step
64
+ 项目未链接且 init 未完成、身份仍歧义、source ref 无效、多组件源码需选策略、平台后端异常、集群容量阻塞、缺少必需 secret、结果仅需人工验证、达到预算、需要破坏性/超范围动作,或进入 code/build handoff 时停止并报告唯一下一步。