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.
- package/README.md +1 -1
- package/SKILL.md +2 -2
- package/bin/rainskills.js +6 -0
- package/install.sh +3 -4
- package/marketplace/rainskills/.claude-plugin/plugin.json +1 -1
- package/marketplace/rainskills/.codex-plugin/plugin.json +1 -1
- package/marketplace/rainskills/skills/rainskills/SKILL.md +3 -3
- package/package.json +2 -2
- package/rainbond-app-assistant/SKILL.md +40 -1452
- package/rainbond-app-assistant/references/operational-reference.md +27 -0
- package/rainbond-app-assistant/references/routing.md +15 -0
- package/rainbond-app-assistant/references/runtime-gate.md +167 -0
- package/rainbond-app-assistant/references/workflow-rules.md +344 -0
- package/rainbond-app-assistant/scripts/validate_cross_skill_routing.py +637 -0
- package/rainbond-app-assistant/scripts/validate_progressive_loading.py +149 -0
- package/rainbond-app-version-assistant/SKILL.md +2 -2
- package/rainbond-delivery-verifier/SKILL.md +2 -2
- package/rainbond-env-sync/SKILL.md +2 -2
- package/rainbond-fullstack-bootstrap/SKILL.md +2 -2
- package/rainbond-fullstack-troubleshooter/SKILL.md +2 -2
- package/rainbond-opensource-app-deploy/SKILL.md +30 -301
- package/rainbond-opensource-app-deploy/agents/openai.yaml +1 -1
- package/rainbond-opensource-app-deploy/references/deployment-workflow.md +168 -0
- package/rainbond-opensource-app-deploy/references/runtime-gate.md +147 -0
- package/rainbond-platform-installer/SKILL.md +1 -1
- package/rainbond-platform-installer/scripts/installed-version.js +1 -1
- package/rainbond-platform-installer/scripts/runtime-state.js +20 -0
- package/rainbond-platform-query/SKILL.md +2 -2
- package/rainbond-project-init/SKILL.md +2 -2
- package/rainbond-template-installer/SKILL.md +2 -2
|
@@ -75,3 +75,30 @@ Load this reference only when checking a proposed route or reviewing a completed
|
|
|
75
75
|
6. if strict delivered and promotion was requested, snapshot and create testing app
|
|
76
76
|
7. verify the testing app once
|
|
77
77
|
8. report one next step
|
|
78
|
+
|
|
79
|
+
## Canonical Model Reference
|
|
80
|
+
|
|
81
|
+
Use `docs/product-object-model.md` as the repository-level source of truth for:
|
|
82
|
+
|
|
83
|
+
- `Project` and `Environment` context boundaries
|
|
84
|
+
- `RuntimeState` distinctions such as topology missing, topology building, and runtime unhealthy
|
|
85
|
+
- `DeliveryState` outcomes such as delivered, delivered-but-needs-manual-validation, partially-delivered, and blocked
|
|
86
|
+
- version-flow handoff boundaries into snapshot, release, and rollback operations
|
|
87
|
+
|
|
88
|
+
This skill should orchestrate transitions across those shared objects and states. It should not redefine their canonical boundaries independently.
|
|
89
|
+
|
|
90
|
+
## Contract Surface
|
|
91
|
+
|
|
92
|
+
This skill now has a live orchestration-level contract surface under:
|
|
93
|
+
|
|
94
|
+
- `schemas/app-assistant-result.schema.yaml`
|
|
95
|
+
- `scripts/validate_app_assistant_output.py`
|
|
96
|
+
- `scripts/run_app_assistant_evals.py`
|
|
97
|
+
- `evals/*.response.md`
|
|
98
|
+
|
|
99
|
+
Scope note:
|
|
100
|
+
|
|
101
|
+
- `AppAssistantResult` is the top-level orchestration contract for this skill
|
|
102
|
+
- `delivery_state` is a consumed summary of `rainbond-delivery-verifier` output, not a redefinition of delivery-verifier rules
|
|
103
|
+
- `promotion_result` is only a gated summary of the version/promotion flow after explicit dev-to-test intent and source-app `delivered`
|
|
104
|
+
- bootstrap / troubleshooter / delivery-verifier contract details remain owned by their own schema + validator + eval surfaces
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# App Assistant routing
|
|
2
|
+
|
|
3
|
+
Use this reference for static ownership decisions before touching Rainbond.
|
|
4
|
+
|
|
5
|
+
This is the default top-level owner for generic current-project deployment, inspection, and repair requests; the request should start here even when a lower-level phase is selected later.
|
|
6
|
+
|
|
7
|
+
## Exclusive deployment routes
|
|
8
|
+
|
|
9
|
+
1. Stay in rainbond-app-assistant for the current project, source code, a source directory or source package, a user-supplied bare Git repository URL, a private-image project, or only an application name. A bare Git URL is source input, not a deployment descriptor.
|
|
10
|
+
2. Route to rainbond-opensource-app-deploy only when the user actually supplies a third-party Docker Compose file/content, Helm chart/values, or a container image-set descriptor.
|
|
11
|
+
3. Route to rainbond-template-installer when a Rainbond local/cloud market template is confirmed.
|
|
12
|
+
|
|
13
|
+
Do not query a market merely to avoid owning a descriptor-less named application. Do not clone or browse a bare Git repository to look for Compose/Helm files before routing: the explicit input boundary decides ownership.
|
|
14
|
+
|
|
15
|
+
After this static choice, load only the selected Skill's Runtime Gate. Never read a neighboring Skill's Runtime Gate.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# App Assistant runtime gate
|
|
2
|
+
|
|
3
|
+
Canonical progressive-loading contract: `rainskills.skill-runtime-contract.v1`.
|
|
4
|
+
|
|
5
|
+
<!-- rainskills-runtime-gate:start -->
|
|
6
|
+
## 单运行环境 CLI 门禁(最高优先级)
|
|
7
|
+
|
|
8
|
+
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true` 后,所有查询和变更直接通过本地 `~/.rainbond/bin/rainskills-tools.js` 执行。不得配置或直接调用客户端 MCP,不得执行环境枚举或业务 operation 生命周期命令,也不得生成或传递运行环境 ID、业务 operation ID 或 intent JSON。
|
|
9
|
+
|
|
10
|
+
没有运行环境时,让用户选择 Rainbond Cloud 或一个已有/新建的私有 Rainbond,并执行对应的 `runtime connect`。连接和重新授权必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT;新凭据通过 live probe 后才覆盖唯一运行环境。CLI 返回 401 时,只读调用可在 `runtime reconnect` 成功后重试一次;写调用不得自动重放,必须先查询平台真实状态。403 直接停止,不重新授权。
|
|
11
|
+
|
|
12
|
+
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"schema": "rainskills.single-runtime-contract.v1",
|
|
17
|
+
"package_version": "rainskills@0.1.23",
|
|
18
|
+
"runtime_status": [
|
|
19
|
+
"node",
|
|
20
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
21
|
+
"runtime",
|
|
22
|
+
"status",
|
|
23
|
+
"--json"
|
|
24
|
+
],
|
|
25
|
+
"runtime_connect": {
|
|
26
|
+
"saas": [
|
|
27
|
+
"node",
|
|
28
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
29
|
+
"runtime",
|
|
30
|
+
"connect",
|
|
31
|
+
"<target>",
|
|
32
|
+
"--saas"
|
|
33
|
+
],
|
|
34
|
+
"private_existing": [
|
|
35
|
+
"node",
|
|
36
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
37
|
+
"runtime",
|
|
38
|
+
"connect",
|
|
39
|
+
"<target>",
|
|
40
|
+
"--rainbond-url",
|
|
41
|
+
"<console-origin>"
|
|
42
|
+
],
|
|
43
|
+
"install_private": [
|
|
44
|
+
"node",
|
|
45
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
46
|
+
"runtime",
|
|
47
|
+
"connect",
|
|
48
|
+
"<target>",
|
|
49
|
+
"--install-private",
|
|
50
|
+
"--location",
|
|
51
|
+
"<local-or-server>"
|
|
52
|
+
],
|
|
53
|
+
"reconnect": [
|
|
54
|
+
"node",
|
|
55
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
56
|
+
"runtime",
|
|
57
|
+
"reconnect",
|
|
58
|
+
"<target>"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"input_commands": {
|
|
62
|
+
"context_resolve": {
|
|
63
|
+
"argv": [
|
|
64
|
+
"node",
|
|
65
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
66
|
+
"context",
|
|
67
|
+
"resolve",
|
|
68
|
+
"--input",
|
|
69
|
+
"-",
|
|
70
|
+
"--skill-id",
|
|
71
|
+
"rainbond-app-assistant"
|
|
72
|
+
],
|
|
73
|
+
"stdin": {
|
|
74
|
+
"required": [
|
|
75
|
+
"enterprise",
|
|
76
|
+
"workspace"
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"read": {
|
|
81
|
+
"argv": [
|
|
82
|
+
"node",
|
|
83
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
84
|
+
"read",
|
|
85
|
+
"<tool>",
|
|
86
|
+
"--input",
|
|
87
|
+
"-",
|
|
88
|
+
"--skill-id",
|
|
89
|
+
"rainbond-app-assistant"
|
|
90
|
+
],
|
|
91
|
+
"stdin_schema_source": "tool-catalog"
|
|
92
|
+
},
|
|
93
|
+
"call": {
|
|
94
|
+
"argv": [
|
|
95
|
+
"node",
|
|
96
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
97
|
+
"call",
|
|
98
|
+
"<tool>",
|
|
99
|
+
"--input",
|
|
100
|
+
"-",
|
|
101
|
+
"--skill-id",
|
|
102
|
+
"rainbond-app-assistant"
|
|
103
|
+
],
|
|
104
|
+
"stdin_schema_source": "tool-catalog"
|
|
105
|
+
},
|
|
106
|
+
"call_confirm": {
|
|
107
|
+
"argv": [
|
|
108
|
+
"node",
|
|
109
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
110
|
+
"call",
|
|
111
|
+
"<tool>",
|
|
112
|
+
"--input",
|
|
113
|
+
"-",
|
|
114
|
+
"--skill-id",
|
|
115
|
+
"rainbond-app-assistant",
|
|
116
|
+
"--confirm",
|
|
117
|
+
"<confirmation-id>"
|
|
118
|
+
],
|
|
119
|
+
"stdin_schema_source": "same-confirmed-input"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
<!-- rainskills-runtime-gate:end -->
|
|
125
|
+
|
|
126
|
+
受限沙箱(包括 Codex)执行本地状态命令时,必须申请用户级受保护目录访问权限;在 Codex 中使用 `require_escalated`。不得修改 `~/.rainbond` 权限、复制受保护状态到工作区,或因沙箱权限错误建议重装。
|
|
127
|
+
|
|
128
|
+
`runtime connect` 的 Device Flow 不依赖 stdin TTY;Agent 必须执行固定 argv 并保持进程附着直到授权完成。能打开本机浏览器时由连接器自动跳转,SSH、容器等无浏览器场景原样展示授权地址并继续轮询。只有 Rainbond 不支持 Device Flow 且进入旧版 loopback 手动粘贴时才需要交互终端;不得要求用户在聊天中粘贴 JWT。
|
|
129
|
+
|
|
130
|
+
执行优化:同一会话内只检查一次 Node.js(首次使用本地 CLI 前);仅在 Node.js 或 Rainskills 安装、升级,或 PATH 变更后失效。固定 launcher 和 argv 已在本 Skill 中,禁止读取、搜索或探测 `rainskills.js`,也禁止执行 `npm root -g`。每个新的业务操作仍需要刷新一次环境列表;带已有 `operation_id` 或 `onboarding-id` 的续接复用已绑定的环境 ID,不重复枚举环境。
|
|
131
|
+
|
|
132
|
+
<!-- rainskills-runtime-routing:start -->
|
|
133
|
+
## 缺少运行环境时
|
|
134
|
+
|
|
135
|
+
先确认 intent 属于 new scope 还是 existing scope;确认前不展示环境选项。
|
|
136
|
+
|
|
137
|
+
### 意图不明确
|
|
138
|
+
|
|
139
|
+
用户请求没有明确指向新应用或已有应用时,只问:“这是要部署新应用还是管理已有应用?”确认前不连接运行环境,也不展示任何环境选项。
|
|
140
|
+
|
|
141
|
+
### 新应用
|
|
142
|
+
|
|
143
|
+
用户明确要部署新应用后,先执行本地 launcher + `["runtime", "message", "--id", "new-application-environment"]`。收到 `[RAINSKILLS_USER_MESSAGE_BEGIN:<id>]` 与对应 END marker 后,只原样输出两者之间的正文,不输出 marker,不得总结、改写、调整项目符号或追加其它说明。下方文案仅用于核对,不得由 agent 自行生成:
|
|
144
|
+
|
|
145
|
+
> 可以,我会帮你完成应用识别、构建、部署和访问验证。
|
|
146
|
+
>
|
|
147
|
+
> 不过目前还没有可用的应用运行环境。
|
|
148
|
+
>
|
|
149
|
+
> 你刚安装的 Rainskills 是负责“部署”的 AI 助手,它会分析项目并执行部署流程;Rainbond 负责为应用提供稳定运行环境。
|
|
150
|
+
>
|
|
151
|
+
此时只保存用户已经明确提供的 intent 字段。`deploy`/`create` 可以只保存 `type`;不得为了构造 runtime intent 提前补参数,平台安装完成前不得询问应用来源,包括本地项目路径、Git 仓库 URL、镜像地址或安装包路径。运行环境连接并通过验收后,恢复到 `project-analysis`,再识别当前项目或询问缺失的应用来源。
|
|
152
|
+
|
|
153
|
+
#### 选择运行环境
|
|
154
|
+
|
|
155
|
+
请提示“请选择应用要运行的环境:”,并只显示:
|
|
156
|
+
|
|
157
|
+
1) 云端环境(免费体验)
|
|
158
|
+
2) 本机环境
|
|
159
|
+
3) 独立服务器
|
|
160
|
+
4) 已有 Rainbond
|
|
161
|
+
|
|
162
|
+
选择 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`。不得显示“私有环境”或部署位置中间层,不得在平台安装器中重复询问部署位置,也不得在环境准备完成前询问应用来源。
|
|
163
|
+
|
|
164
|
+
### 已有应用
|
|
165
|
+
|
|
166
|
+
用户明确要查询、排障、修改或验证已有应用时,使用与动作匹配的第一句话,只提供 `Rainbond Cloud` 或承载目标应用的`已有私有 Rainbond`。选择已有私有 Rainbond 时执行本地 launcher + `["runtime", "message", "--id", "private-console-origin"]` 并原样输出。已有应用不得安装新平台,也不得进入 install-private。
|
|
167
|
+
<!-- rainskills-runtime-routing:end -->
|
|
@@ -341,3 +341,347 @@
|
|
|
341
341
|
- the cluster is capacity-blocked and a human must decide whether to scale capacity or reduce requests
|
|
342
342
|
- a required secret source is missing
|
|
343
343
|
- a code/build handoff is required and the user has not asked for code changes
|
|
344
|
+
|
|
345
|
+
## 硬规则
|
|
346
|
+
|
|
347
|
+
以下规则优先级最高。若后文示例、详细说明或历史注释与这里冲突,以这里为准。
|
|
348
|
+
|
|
349
|
+
1. 只读取当前项目目录中的 `rainbond.app.json`、`.rainbond/local.json`、环境文件和 secrets 文件。
|
|
350
|
+
不允许扫描 `$HOME`、上级目录或其他仓库来“补绑定”。
|
|
351
|
+
2. **team / app 智能选择**:
|
|
352
|
+
- 单个 team 可访问 → 直接用,不询问。
|
|
353
|
+
- 多个 team 但 manifest(`rainbond.app.json` / `.rainbond/local.json`)显式指定了 `team_name` 且该 team 在可访问列表里 → 直接用,在报告里明确说"已选 team = X(来自 manifest)"。
|
|
354
|
+
- 多个 team 且无 manifest 提示 → 停下来询问用户,**禁止**静默选 `default` / 第一个 / 任意已有 team。
|
|
355
|
+
- app 选择同上逻辑:manifest 指定且可解析 → 直接用;无提示且多候选 → 询问。
|
|
356
|
+
- 任何自动选择的结果都必须在最终报告里以"已选 X(理由:来自 manifest / 单一可选)"形式告知,邀请用户覆盖。
|
|
357
|
+
- 每个 Rainbond MCP 工具边界都要把十进制字符串 `app_id` 规范化为正整数;非数字 ID 必须拒绝。
|
|
358
|
+
3. 单入口主线一旦触发:
|
|
359
|
+
`project-init -> bootstrap -> troubleshooter -> delivery-verifier -> version-assistant -> testing-app delivery-verifier`
|
|
360
|
+
应按 gate 自动继续,不要在中途停成“下一步建议”。
|
|
361
|
+
4. `project-init` 成功 linked 后,如果当前 run 是单入口部署/开发到测试主线,必须自动继续到 `bootstrap`。
|
|
362
|
+
5. 当前项目一旦被判定为 `source-backed`,不能静默改成 `package` 或 `image`。
|
|
363
|
+
transport 代理只改“怎么拉”,不改 delivery mode。
|
|
364
|
+
6. **传输代理自动决策(Git URL + image 公网拉取统一处理)**:当组件源指向**已知有可工作代理的公网服务**时,**默认自动套用代理**,不打断流程问用户,在最终报告里明确告知"已用 X 代理拉取 Y",邀请用户覆盖。其它情况按下面分类处理。
|
|
365
|
+
|
|
366
|
+
**已知可工作的代理 pair(限定清单 — 这里必须用清单,不能用 principle,因为代理 URL 是事实,不能让模型推断)**:
|
|
367
|
+
- `github.com` Git URL → `https://ghfast.top/<原完整 URL>`(含 `https://github.com/...`、`https://raw.githubusercontent.com/...`)
|
|
368
|
+
- `docker.io` 容器镜像(含裸 `nginx:latest`、`library/...` 这种隐式解析为 `docker.io/library/...` 的引用)→ `docker.1ms.run/<dockerhub-path>`
|
|
369
|
+
|
|
370
|
+
**其它公网 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` 等及其它公网服务):
|
|
371
|
+
- **禁止瞎拼代理 URL**(如 `docker.1ms.run/quay.io/...`、`docker.1ms.run/nvcr.io/...` 都不是有效路径 — 这些公网代理只针对自己声明的源仓库工作)
|
|
372
|
+
- 默认**先用原 URL 试**,不主动套代理
|
|
373
|
+
- 如果用户在消息里明确给出了代理 URL(如 `请用 https://my-proxy/quay.io/calico/node`),照用
|
|
374
|
+
- 如果出现拉取失败(`ImagePullBackOff`、`Manifest not found`、`connection refused`),**这时才**询问用户:"`quay.io/...` 拉取失败,可能是网络问题。您是否有可用的代理?或者继续重试原 URL?"
|
|
375
|
+
|
|
376
|
+
**私有 / 自建 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` 等用户专属路径)。模型用通用知识识别,不需要等清单。
|
|
377
|
+
|
|
378
|
+
**已在镜像源的 URL**(前缀已是 `docker.1ms.run`、`m.daocloud.io`、`mirror.gcr.io`、`ghfast.top/...` 等):直接通过,不重复代理。
|
|
379
|
+
|
|
380
|
+
一次 run 内复用同一代理前缀,不并存多个。用户明确说"不用代理"或"用原始地址" → 当次 run 内对所有 in-scope URL 都跳过代理。
|
|
381
|
+
|
|
382
|
+
> 编号说明:原 Iron Law 7(image 代理 ask once)已合并到本条;后续 Iron Law 编号保留原值(8、9、10…),不重编号以免破坏跨规则引用。
|
|
383
|
+
> 措辞说明:代理 URL 是**事实信息**(哪个代理服务真的能 proxy 哪个源),必须写清单 — 这跟 Iron Law 37 把"基础设施软件"写成 principle 是不同性质。不要把这里的清单也"principle 化",否则模型会瞎拼无效代理 URL。
|
|
384
|
+
8. 一旦 source ref 已确定,不能静默改 branch/ref。
|
|
385
|
+
分支不存在时必须停住并报告 source definition needs confirmation。
|
|
386
|
+
9. `check_uuid` / `event_id` 默认不是标准 source create 的前置条件。
|
|
387
|
+
除非后端明确返回它们必需,否则不能把它们当 blocker。
|
|
388
|
+
10. 如果 source create 返回 `multiple services detected` 或等价的多组件源码歧义,必须停住,要求用户明确选择策略。
|
|
389
|
+
不允许自动切到 local package、手工上传、模板安装或其他 workaround。
|
|
390
|
+
11. 如果进入 `code_or_build_handoff_needed`,必须硬停止。
|
|
391
|
+
不允许自动改代码、跑本地测试、commit、push、自动重试。
|
|
392
|
+
12. `delivery_state` 只表示 source app。
|
|
393
|
+
在没有运行 `delivery-verifier` 之前必须是 `null`。
|
|
394
|
+
`promotion_result` 只表示 snapshot 和 testing app;未进入 promotion 时必须是 `null`。
|
|
395
|
+
13. 顶层主线必须有尝试预算:
|
|
396
|
+
- 同一类错误签名最多重试 1 次
|
|
397
|
+
- 同一阶段最多尝试 2 次(首次 + 1 次重试)
|
|
398
|
+
- 单次主线总时长默认不应超过 8 分钟;超时后必须停止并汇报当前停点。
|
|
399
|
+
14. 任何 delivery mode 或 workaround 策略切换都不允许隐式发生。
|
|
400
|
+
source -> package、source -> image、source -> template 都必须先得到用户明确确认。
|
|
401
|
+
15. 如果用户明确在问“为什么构建失败”,顶层必须优先走 `component events -> build logs -> runtime logs` 的构建失败证据链。
|
|
402
|
+
不要把运行容器日志当第一现场。
|
|
403
|
+
16. 如果用户要求调整源码构建参数,优先走 `rainbond_manage_component_envs(operation=replace_build_envs, build_env_dict=...)`。
|
|
404
|
+
不要把语言构建参数塞进 `build_info`。
|
|
405
|
+
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`。
|
|
406
|
+
- **恢复例外按状态决定**:`checking` / `checked` / 未完成组件可以通过 `rainbond_get_component_check_result(prefer_dockerfile_when_detected=true)` 在原拓扑中取得 Dockerfile 证据,禁止删除。只有 `create_status=complete` 的 CNB 组件不存在通用原地切换能力时,才允许在已保存 topology and configuration snapshot、已向用户展示该完成状态并获得 explicit user confirmation 后删除并重建;任一证据缺失时只读停止。
|
|
407
|
+
18. 当前 MCP 不支持显式 `dockerfile_path` 时,不要在顶层编排里承诺该能力。
|
|
408
|
+
19. 对 reverse-proxy full-stack 项目,不要只因为根路径 URL 存在就把它当作最终交付成功或 Fast Path 的可信 URL;同 host 的 backend 路径(通常是 `/api`)必须也一致可用,或明确停在 blocker。
|
|
409
|
+
20. **组件依赖与连接变量管理**(合并自原 20-23 四条):多组件拓扑里,provider/consumer 关系必须用显式依赖 + provider 侧连接变量管理,不要让 consumer 端硬编码或重复声明。
|
|
410
|
+
|
|
411
|
+
**可执行工具(fact)**:
|
|
412
|
+
- 显式依赖:`rainbond_manage_component_dependency` — 不要回答"MCP 没有依赖接口";调用失败时按 MCP/控制面真实错误报告,不要描述为工具不存在
|
|
413
|
+
- Provider 连接变量:`rainbond_manage_component_connection_envs(scope=outer)` — 这是 provider 暴露给 consumer 的接口面
|
|
414
|
+
- Consumer 自身的本地 env:`rainbond_manage_component_envs` — 仅放该 consumer 真正本地的值
|
|
415
|
+
|
|
416
|
+
**判断顺序(principle)**:
|
|
417
|
+
- 拓扑里出现 provider/consumer 关系(`depends_on`、反向代理链路、运行时日志暴露的连接错误)→ 用 `rainbond_manage_component_dependency` 建显式依赖
|
|
418
|
+
- 共享连接信息(数据库连接串、缓存地址、消息队列 broker 等任何"provider 拥有的连接 fact")→ 配在 provider 的 connection envs 上,**不要**在每个 consumer 上重复写
|
|
419
|
+
- 运行时报 `connection refused` / `ENOTFOUND <provider-name>` / 错 host / 错 port / 缺密码等连接类错误 → 先看 provider connection env / dependency alias / compatibility env,**不要**把 baseline 里的硬编码主机名当成事实
|
|
420
|
+
- 多组件拓扑进入交付验收前 → 必须跑一遍依赖完整性 gate(列已接受边 → 查现有依赖 → 补齐缺失 → 再次验证依赖摘要)。手工创建镜像组件、Compose fallback 路径、组件能独立启动都**不能**跳过 gate
|
|
421
|
+
- **配置覆盖 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 就当成功
|
|
422
|
+
|
|
423
|
+
具体的 provider 命名约定、connection env 变量名(`DB_*` / `REDIS_*` / `KAFKA_*` 等是示例,按 provider 文档实际名字为准)、以及依赖 alias 细节,详见 bootstrap modules/30-creation-rules.md 的相关章节。
|
|
424
|
+
24. 不要自动拉起本地 Docker Desktop/OrbStack、执行本地 Docker build/push、或推送临时镜像作为兜底;这属于 delivery-mode 策略切换,必须先得到用户明确确认。
|
|
425
|
+
25. 每次运行内部仍必须形成 `AppAssistantResult` 结果对象,但默认用户答复不一定暴露 YAML。
|
|
426
|
+
当 `source_app_delivery` 的 runtime healthy、没有 blocker、控制台部署位置和公网访问地址都已确定,且 delivery 已 `delivered` 或只剩浏览器人工确认时,默认使用简洁中文交付报告,不追加 `### Structured Output`。
|
|
427
|
+
26. 只有在自动化/评测明确要求结构化契约,或用户明确要求 YAML、JSON、调试详情、内部状态对象时,才把 `AppAssistantResult` 渲染为最终 fenced `yaml`。部署失败、仍在构建、存在 blocker/handoff/身份歧义或进入 dev-to-test promotion 都不是默认暴露 YAML 的理由。
|
|
428
|
+
27. 如果本次使用了 Git、镜像仓库或其他传输代理,必须在默认交付报告的处理记录或注意事项中说明;在结构化模式下也必须写入 `actions_performed[].details`。
|
|
429
|
+
代理事实属于执行记录,不是强制暴露 YAML 的理由。
|
|
430
|
+
28. `rbd-*` 组件(rbd-gateway、rbd-api、rbd-worker、rbd-chaos、rbd-db、rbd-mq、rbd-monitor、rbd-node 等)是 Rainbond 平台自身的基础设施组件,不是用户应用组件。
|
|
431
|
+
- 可以用 `rainbond_query_region_rbd_components` 查询并展示它们的状态
|
|
432
|
+
- 不能通过 MCP 对它们执行重启、部署、修改等写操作;当前 MCP 工具集不支持此类操作
|
|
433
|
+
- 如果用户要求操作这些组件,明确告知:需要通过 Kubernetes 命令(如 `kubectl rollout restart deployment/<name> -n rbd-system`)或 Rainbond 集群管理控制台进行,超出本技能的操作范围,不要假装可以执行
|
|
434
|
+
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,也不查询组件残留。
|
|
435
|
+
`event_log_tail` 只作为敏感诊断证据使用,绝不能复制、引用或向用户展示其原文;输出只能使用 `classified_reason`、非敏感摘要和已脱敏字段。
|
|
436
|
+
28b. 运行态或交付健康检查先调用 `rainbond_get_app_health_overview`;仅 `abnormal` 或 `unknown` 组件再读取 component summary、日志、事件或存储明细。
|
|
437
|
+
29. **仅给 bare Git URL 时默认 root + 空 `subdirectories`**:当用户给的只是一个 Git URL(无本地 manifest、无明确子目录提示),默认 `subdirectories=""`(仓库根)进入 source 检测,让后端判断这个仓库结构。**不要**先问用户"根目录还是子目录"。
|
|
438
|
+
- 单项目仓库(一个 buildable root)→ 后端检测通过,正常 build
|
|
439
|
+
- 多组件 / 多 example 仓库 → 后端返回 `multiple services detected` 或等价歧义信号 → 按 Iron Law 10 停下问用户选哪个子目录
|
|
440
|
+
- 模型**禁止**凭训练知识枚举子目录或猜测路径(由 Iron Law 36 强制 — `subdirectories` 是受 verbatim 保护的字段之一)
|
|
441
|
+
- 把"是否需要选子目录"这个判断**外包给后端检测**,不要前置询问;前置询问只在用户的需求文本本身就说了"我只要这个仓库的 X 子目录"这类显式信号时才有意义(这时直接 verbatim 用用户给的子目录字面值)
|
|
442
|
+
30. 源码创建一旦失败,**绝对禁止**第二次调用 `rainbond_create_component_from_source` 来"换参数重试",也**绝对禁止**通过 `rainbond_delete_component` 删掉失败组件再 create 这种伪装手段绕过预算。
|
|
443
|
+
`rainbond_create_component_from_source` 是"检测 + 创建 + 构建"三合一工具,**不是幂等重试工具**,每次调用都会写入一个新的 `service_id`。调用报错不代表组件没建出来——组件行、端口、env、依赖可能已经存在,错误只发生在下游检测或构建阶段;不能凭"上次 create 调用我没拿到 service_id 所以肯定没建出来"做臆测。
|
|
444
|
+
本轮任何源码失败(包括"源码目录不存在 / 子目录识别不到 / 多组件歧义 / 仓库不可达 / 检测识别不到语言 / 构建失败"等)之后,第二个动作**必须**按以下纪律走:
|
|
445
|
+
- 第一步永远先 `rainbond_query_components` 查目标 app,按 `service_cname` 或 `k8s_component_name` 匹配;只要查到一条同名/相近的组件,就视为已存在
|
|
446
|
+
- 命中已存在:
|
|
447
|
+
- 同 `git_url` 同 `code_version`,只想重跑构建 → `rainbond_build_component(service_id, build_info=...)`
|
|
448
|
+
- 源码定义改了(`git_url` / `code_version` / `subdirectories` / `server_type` / 凭据) → `rainbond_update_component_build_source` 然后 `rainbond_build_component`
|
|
449
|
+
- 只调构建参数 → `rainbond_manage_component_envs(operation=replace_build_envs, build_env_dict=...)` 然后 `rainbond_build_component`
|
|
450
|
+
- 未命中(`rainbond_query_components` 确认目标 app 下不存在任何对应组件)才允许重新调 `rainbond_create_component_from_source`,且仍然受 Iron Law 14 的尝试预算约束。
|
|
451
|
+
典型反例(**禁止**):第一次报"源码目录不存在" → 第二次换个 `subdirectories` 再 create → 第三次又换大小写再 create。每次都会产出新的 service_id,留下多个垃圾组件需要用户清理。正确路径:先 `rainbond_query_components`,如果已经留下了某个 `java-maven-demo` 组件,就 `rainbond_update_component_build_source` 改 `subdirectories` 再 `rainbond_build_component`;只有确认 app 下完全没有同名组件,才可以重新 create,并且必须遵守"同一阶段最多 2 次"。
|
|
452
|
+
**以 `service_cname` 为预算基本单位**:Iron Law 14 的"同一阶段最多尝试 2 次"按 `service_cname` 累计计数,**`rainbond_delete_component` 不重置这个计数**。换句话说,对同一个 `service_cname`(例如 `java-maven-demo`)在本轮 run 内 `create_from_source` 类工具的调用总次数最多 2 次,不管中间有没有 `delete_component` 把上一次的失败组件清掉;超过即必须停下来按下面"用户输入错误"流程走。
|
|
453
|
+
**用户输入错误必须停下来问用户,不允许猜参数**:当源码检测明确报"源码目录不存在 / 语言识别失败 / 仓库不可达 / 凭证错误"等**用户输入相关**的错误时,根因是用户给的 `git_url` / `subdirectories` / `code_version` / 凭证本身有问题——这类错误**不能通过 AI 自己换参数**(去掉 subdirectories、改大小写、换分支名、换 case)来解决。必须**停下来**显式询问用户:
|
|
454
|
+
- 列出已尝试的参数组合和对应的错误信息
|
|
455
|
+
- 请用户确认仓库的真实子目录路径(建议用户在浏览器打开仓库或贴 tree 截图)
|
|
456
|
+
- 或者请用户提供另一个分支 / 凭证 / 子路径
|
|
457
|
+
- **不允许**根据"模型对该仓库的先验知识"猜常见名字(Java-maven-demo、java_maven_demo、demo/java-maven 等)
|
|
458
|
+
- 这与 Iron Law 29 入口"必须问用户"配套:29 管入口、30 管中途用户输入验证失败的二次询问。
|
|
459
|
+
猜测换参数 + 删-再-create 循环是典型 anti-pattern,server 端可能直接 reject 重复 create 调用。
|
|
460
|
+
31. **任何 Rainbond MCP 写工具调用之前**,必须先按下面的映射调用对应的 `select_skill_<id>` 工具,把该阶段的执行手册加载进会话上下文;没先调 `select_skill_<id>` 就直接动手等于**无授权操作**,是 Iron Law 违反。
|
|
461
|
+
触发动作(凡是这类,第一次调之前都必须先 `select_skill_<id>`):
|
|
462
|
+
- 创建/更新/部署组件:`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`
|
|
463
|
+
- 包上传事务:`rainbond_init_package_upload`、`rainbond_delete_package_upload`;包内容必须由 bootstrap 的客户端 helper 上传,完成后再用上面的 event-based package create
|
|
464
|
+
- 组件配置:`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`
|
|
465
|
+
- 应用操作:`rainbond_operate_app`、`rainbond_horizontal_scale_component`、`rainbond_vertical_scale_component`、`rainbond_delete_component`
|
|
466
|
+
映射表:
|
|
467
|
+
- 当前 run 是**首次部署/创建组件/补齐拓扑**(含从源码/镜像创建,以及客户端 package upload + event-based package create) → 在第一个 MCP 写调用之前调 `select_skill_rainbond-fullstack-bootstrap`
|
|
468
|
+
- 当前 run 是**排查运行态/构建失败**(CrashLoopBackOff / ImagePullBackOff / 构建报错 / 端口/依赖不通) → 在第一个 MCP 写调用之前调 `select_skill_rainbond-fullstack-troubleshooter`
|
|
469
|
+
- 当前 run 是**交付验收**(验证 URL 可达、reverse-proxy 路径连通) → 调 `select_skill_rainbond-delivery-verifier`
|
|
470
|
+
- 当前 run 是**开发到测试 promotion**(创建快照 + 测试 app) → 调 `select_skill_rainbond-app-version-assistant`
|
|
471
|
+
- 当前 run 是**模板安装**(本地/云端 Rainbond 应用模板) → 调 `select_skill_rainbond-template-installer`
|
|
472
|
+
规则细节:
|
|
473
|
+
- `select_skill_<id>` 本身不需用户审批、不消耗 MCP,但它的调用是**前置门控**,没调不允许走下去
|
|
474
|
+
- 一个 skill 在同一次 run 内只需调一次(重复调用工具会返回 "already active" ack)
|
|
475
|
+
- **判断依据**:用户消息中只要含"部署 / 跑起来 / 上线 / 创建组件 / 发布"等部署意图,且当前 app 还没有对应组件,就必然要先 `select_skill_rainbond-fullstack-bootstrap`,不论用户是不是显式说"先 deep dive"
|
|
476
|
+
- 如果一次 run 内场景跨阶段(先创建后排障),按需追加 `select_skill_<id>`,旧的不会被卸载
|
|
477
|
+
正确路径:用户说"试试 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` 的结果。
|
|
478
|
+
32. **简短回复继承上一轮被中断的操作**:当上一轮你向用户提了问、或在 prose 里邀请用户回复("回复继续 / check / OK / 完成 / 重试" 等),用户给了简短或单值回复("继续"、"OK"、"试试 X"、"对的就是 Y"、"换 master"),你的**下一个动作必须基于 priorTurnMessages 的最新状态继续上一个被中断的操作**,**禁止**把它当成一次"全新的开始"。
|
|
479
|
+
- 看 priorTurnMessages 里上一条 assistant 消息:以问号结尾 / 含"回复 X / 你看 / 是否 / 请确认 / 请选" → 视为对你提问的回答
|
|
480
|
+
- 用户上一轮如果在等"build 完成"、"poll status"、"check 进度"等异步状态,简短回复就是"继续轮询" → 直接调对应的状态查询工具(`rainbond_get_component_summary` / `_build_logs` / `_events` 等)
|
|
481
|
+
- 用户上一轮在等"换参数后的重新检测结果",简短回复就是"用新值重跑" → 直接调修改类工具(update_build_source → check → poll,见 Iron Law 33)
|
|
482
|
+
- **禁止**:本轮重新走"加载 skill / 询问意图 / 查 app 详情 / 列能力清单"的初始化流程
|
|
483
|
+
- **例外**:用户消息明显是新任务("换个项目"、"算了别部署了"、"先停下"),按新任务处理
|
|
484
|
+
- 信号词识别:"继续 / check / OK / 完成了吗 / 现在怎样 / 进度 / 试 X" 这类短词 → 多半属于回答;超过一句完整描述新任务的才算 fresh intent
|
|
485
|
+
33. **`rainbond_update_component_build_source` 只改 DB 不触发检测**,调完之后下一个 MCP 写调用**必须**是 `rainbond_check_component(service_id=..., is_again=true)`,不允许中间夹任何其他工具,也不允许跳过它直接读 check_result 或调 build。
|
|
486
|
+
背景(必读):后端 `update_component_build_source` 视图仅把 `git_url`/`subdirectories`/`code_version`/凭证字段写进 DB(`service.save()` 结束),**没有调用 `app_check_service.check_service`**。因此:
|
|
487
|
+
- 改完 build_source 后调 `rainbond_get_component_check_result` → 返回的依然是**上一轮**(最初 create 时)的 `check_uuid` 和 "源码目录不存在" 旧结果,给人"我的修改没生效"的假象,实际是检测根本没重跑
|
|
488
|
+
- 改完 build_source 后调 `rainbond_build_component` → 组件还停留在 `service_source=source_code` + 上轮检测未通过的状态,build 任务会被卡在 `checking`,无法真正启动
|
|
489
|
+
- 唯一能让后端重跑源码检测的方式是 `rainbond_check_component(is_again=true)`(对应 `app_check_service.check_service(team, service, is_again=True, ...)`,会清掉旧的 `check_uuid` 并发起新一轮 check_event)
|
|
490
|
+
强制时序模板:
|
|
491
|
+
```
|
|
492
|
+
rainbond_update_component_build_source(service_id, git_url?, subdirectories?, code_version?, ...)
|
|
493
|
+
↓ 立刻
|
|
494
|
+
rainbond_check_component(service_id, is_again=true)
|
|
495
|
+
↓ 拿到新的 check_event_id / check_uuid
|
|
496
|
+
rainbond_get_component_check_result(service_id) # 轮询直到 check_status != "checking"
|
|
497
|
+
↓ 通过
|
|
498
|
+
rainbond_build_component(service_id, build_info=...)
|
|
499
|
+
```
|
|
500
|
+
禁止序列:
|
|
501
|
+
- `update_component_build_source` → `get_component_check_result`(中间没 `check_component`)
|
|
502
|
+
- `update_component_build_source` → `build_component`(中间没 `check_component`,组件仍 `checking`,build 必失败)
|
|
503
|
+
- 多次 `update_component_build_source` 之间不夹 `check_component`(等价于在改了 DB 但没触发检测的情况下又改一遍,每次轮询的还是同一个旧 `check_uuid`)
|
|
504
|
+
与 Iron Law 30 配套:30 管"换参数重试"的预算(同 `service_cname` 最多 2 次 create / 同 service_id 同字段最多 N 次 update),33 管"改完后必须走完一个完整 check 闭环"。两者一起堵住"猜参数 → 改了又不重检测 → 又看到旧错误 → 再猜"的死循环。
|
|
505
|
+
34. **service_id provenance:任何 MCP 写工具传入的 `service_id` 必须有明确出处**,不允许凭模型记忆或上下文里飘着的 UUID 猜。
|
|
506
|
+
合法的 `service_id` 来源(按优先级):
|
|
507
|
+
- 本会话内 `rainbond_query_components` 的返回结果(最新一次)
|
|
508
|
+
- 本会话内 `rainbond_create_component_*` 工具的返回值
|
|
509
|
+
- `session.localBinding.serviceId` / `priorTurnMessages` 里同一 `service_cname` 的 ack
|
|
510
|
+
不合法的 `service_id` 来源(**禁止**):
|
|
511
|
+
- 从对话历史里随手抓一个看起来像 UUID 的字符串(可能是 `check_event_id` / `check_uuid` / `event_id` / 历史 service_id)
|
|
512
|
+
- 凭"我记得是这个"或"上次也是这个 ID"做猜测
|
|
513
|
+
- 用户消息里粘的、但本会话没验证过的 ID
|
|
514
|
+
强制流程:动手前如果不能 100% 确定 `service_id` 出处,**第一动作**必须是 `rainbond_query_components({enterprise_id, app_id})`,必要时携带 `query=<service_cname 或 service_id>`,按 `service_cname` 或 `k8s_component_name` 匹配出真实 `service_id`,再调写工具。
|
|
515
|
+
反例(**禁止**):日志里出现"修改组件 `7059eb62cccc3a16f22c9415c905bbcc` 的构建源" — 这个 ID 在本会话所有 query 结果里都没出现过,是模型从某处幻觉出来的。正确做法:调 update 之前先 `rainbond_query_components` 拿到真实 `service_id`,再 update。
|
|
516
|
+
与 Iron Law 31 配套:31 管"写工具前必须 select skill",34 管"写工具的 service_id 必须有明确出处"。两条共同把"模型自由发挥参数"这条路堵死。
|
|
517
|
+
|
|
518
|
+
**同样的 provenance 规则对 `event_id` 生效**:调 `rainbond_get_component_build_logs` / `rainbond_get_app_upgrade_record` 等需要 `event_id` 的工具时,`event_id` 必须是**真实 UUID**(如 `805f6397871d467b968d14c3575082a6`),合法来源仅限:
|
|
519
|
+
- 本会话内 `rainbond_get_component_events` 返回的 `events[*].event_id`
|
|
520
|
+
- 本会话内写工具(`rainbond_build_component` / `rainbond_operate_app` / `rainbond_check_component` 等)响应里的 `event_id` / `build_event_id` / `check_event_id`
|
|
521
|
+
|
|
522
|
+
不合法 `event_id` 来源(**禁止**):
|
|
523
|
+
- `rainbond_get_component_summary` 返回的 `recent_events[*].ID` — 这是**数据库自增行号**(如 `17740`),**不是** UUID
|
|
524
|
+
- 任何看起来是短整数的字段(4-6 位数字)
|
|
525
|
+
- 历史会话里飘着的、本会话未通过 events 查询验证过的字符串
|
|
526
|
+
|
|
527
|
+
强制流程:调用任何 `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,再调下游工具。
|
|
528
|
+
|
|
529
|
+
反例(来自真实回归 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` 重查。
|
|
530
|
+
35. **会话内部叙述纪律 + 内部 preflight 工具不要主动调**。下列四类是"内部会话状态",对用户**无信息量**,禁止外漏到 assistant 可见消息:
|
|
531
|
+
- **`select_skill_*` 工具调用本身**:这是 server 内部 hookup,把指定 skill 的执行手册拼到 system prompt 用的。调用前**不要**说"我先加载 bootstrap 手册"、"现在调用 select_skill_...";调用后**不要**说"Bootstrap 手册已加载"、"skill ready" 这类回声。server 返回的 `loaded_skill` / `already active` ack 是给你看的内部信号,**直接进入下一个真实工具调用**,保持沉默。
|
|
532
|
+
- **`rainbond_get_current_user`**:不得由 Agent 单独调用。企业、工作空间和集群上下文统一由受保护的 `context resolve` 命令解析并绑定到本次 operation;只有 CLI 明确返回需要选择时才询问用户。
|
|
533
|
+
- **`rainbond_query_components` 同入参重复轮询**:服务端 30s 内的同 args 调用会走缓存;你**不要**在每个新 user turn 开头都"先查一下组件列表",priorTurnMessages 里上一次的 query 结果在 contextSignature 不变时仍然有效。
|
|
534
|
+
- **规则推理过程 / MCP 工具内部限制 / 分类决策叙述**:你内部基于哪条 Iron Law / hard rule / 推断信号做的决策、具体 MCP 工具签名 / 字段限制、对组件 / 服务的分类判断("ClickHouse 是公认的列式分析数据库"这类),都属于内部状态,对用户**无信息量**。
|
|
535
|
+
|
|
536
|
+
**禁止**这类叙述(来自真实回归 case 的典型模式):
|
|
537
|
+
- "ClickHouse 是公认的列式分析数据库,属于基础设施软件,按 image 模式创建"
|
|
538
|
+
- "通过代理 docker.1ms.run/library/clickhouse:latest 加速拉取"(应改为"用镜像代理加速拉取",不要把代理 URL 暴露给用户读)
|
|
539
|
+
- "由于 rainbond_create_component_from_image 不支持直接设置 extend_method,需要先创建再修改"
|
|
540
|
+
- "先加载 bootstrap skill" / "现在我来加载 bootstrap 手册"(参见本规则第 1 类)
|
|
541
|
+
- "根据 hard rule 2 我需要先查 team 列表"
|
|
542
|
+
- "Iron Law 14 要求尝试预算最多 2 次,所以..."
|
|
543
|
+
- "接下来需要:1. 配置端口 2. 挂载存储 3. 部署组件"(流程清单 — 直接调工具,不预告步骤)
|
|
544
|
+
|
|
545
|
+
**判断捷径**:消息里出现 `X 是 Y` / `属于 X 类` / `公认的 X` / `按 X 模式` / `根据 X 规则` / `由于 X 工具不支持` / `先加载 X skill` / `接下来需要:1. 2. 3.` 这些短语多半要删。
|
|
546
|
+
|
|
547
|
+
**改写为结果导向的用户语言**:
|
|
548
|
+
- 一句话开场("好的,我帮你部署 X" — 1 句,超过 1 句就是噪音)
|
|
549
|
+
- 真需要用户回答的问题(多 team 无 manifest 提示 / 关键参数缺失)
|
|
550
|
+
- 工具失败的真实报错信号
|
|
551
|
+
- 最终结构化报告(按 Output Format 章节,结构化字段允许包含 `decision_reasons`)
|
|
552
|
+
|
|
553
|
+
原则:用户关心**结果和你正在做的事**,不关心你**为什么决定这么做**。规则推理 / 工具字段限制 / skill 加载 / 上下文重述对用户无信息量。规则名 / 决策依据 / 工具限制可以在最终报告的 `actions_performed[].details` 或 `decision_reasons` 结构化字段里出现,但 prose 流水里出现就是噪音。
|
|
554
|
+
|
|
555
|
+
> rainagent 运行时通过 server-side "最终覆盖规则" 段也强制了同一条规则;本条主要服务 CLI / Codex 端使用者(他们没有 runtime tail 注入)。
|
|
556
|
+
|
|
557
|
+
**同一个 `<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>` 一次。
|
|
558
|
+
|
|
559
|
+
反例(**禁止**):上一轮已经 `select_skill_rainbond-fullstack-bootstrap` 过了,本轮 user 简短回复 "java/jar",你又调一次 `select_skill_rainbond-fullstack-bootstrap` 并叙述"先加载 bootstrap"。正确做法:priorTurnMessages 已有 ack → 直接 `rainbond_update_component_build_source(...)` 继续。
|
|
560
|
+
正例:上一轮 `select_skill_rainbond-fullstack-bootstrap`,本轮用户说"组件起不来帮我排查下" → 现在阶段从部署切到排障 → 调一次 `select_skill_rainbond-fullstack-troubleshooter`(新 skill,允许)→ 沉默地进入诊断流程,不复述"troubleshooter 已加载"。
|
|
561
|
+
36. **用户给出的字面值(URL / 镜像地址 / 分支名 / 凭证)必须 verbatim 传给工具,禁止 LLM 凭训练知识"补全"、"修正"、"猜测"**。
|
|
562
|
+
适用字段:`git_url` / `image`(用户所说的镜像地址映射到 Console Tool 的 `image` 字段)/ `code_version`(分支/tag/commit)/ `username` / `password` / `token` / `subdirectories` 等任何用户在消息里给出的字面值。
|
|
563
|
+
**禁止行为**:
|
|
564
|
+
- 看到 `service_cname=java-maven-demo` 就自创 `git_url=https://gitee.com/mirrors_123/java-maven-demo.git`(按训练数据里"常见仓库地址"补全)
|
|
565
|
+
- 用户给的 URL 没 `.git` 后缀就自动加上
|
|
566
|
+
- 用户给的 URL 是 `gitee.com/xxx/yyy`,你"知道这个仓库其实在 GitHub" 就改成 `github.com/...`
|
|
567
|
+
- 用户给了主仓库 URL(`https://gitee.com/rainbond/sourcecode-examples`),你把它换成你以为的子项目独立仓库(`https://gitee.com/some-org/java-maven-demo.git`)—— 同一个仓库下的不同子项目应该用**同一个 URL + subdirectories 参数**区分,而不是换 URL
|
|
568
|
+
- 用户没说分支,你自己写 `code_version=main` 或 `master` 当默认值(应该让后端/MCP 默认值生效,传 `master` 的前提是用户说过 master 或者你是 carrying over 从已有组件 build_source 拿到的字面值)
|
|
569
|
+
|
|
570
|
+
**正确做法**:
|
|
571
|
+
- 用户消息里出现的 URL/分支/凭证,**逐字符 copy** 传给工具
|
|
572
|
+
- 用户消息**没有**给某个字段(如只说"部署 X 项目"没给 git_url)→ 必须**问用户**要这个字段,不允许自创
|
|
573
|
+
- 如果你认为用户给的值有问题(域名错、路径不对),**让后端报错**而不是预先"修正"——后端的报错是把决定权交回用户的正确路径
|
|
574
|
+
- 唯一允许"非用户消息字面"的 git_url 来源:本会话内 `rainbond_get_component_build_source` 的返回(即"维持已有组件的 git_url 不变"场景);这种情况下你必须能在 priorTurnMessages 的 tool_result 里指出该值的来源
|
|
575
|
+
|
|
576
|
+
**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 轮次。
|
|
577
|
+
|
|
578
|
+
反例(**禁止**):用户说"帮我部署 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 整个替换成你训练数据里相关性高的某个独立仓库。
|
|
579
|
+
正确做法:`rainbond_create_component_from_source(git_url='https://gitee.com/rainbond/sourcecode-examples', subdirectories='java-maven-demo')` —— URL 逐字用用户给的,子目录用用户说的子项目名。
|
|
580
|
+
37. **组件创建方式智能推断(image vs source vs complex suite)**:用户请求创建组件时,**根据用户消息里的信号自动推断创建方式**,不要停下来问"用镜像还是源码?"。但必须先区分"简单单镜像基础设施"和"复杂现成软件套件":复杂套件不能只凭模型通用知识手搓多组件拓扑。
|
|
581
|
+
|
|
582
|
+
推断信号优先级(从强到弱):
|
|
583
|
+
- 用户提到 Git URL / 分支 / commit / `subdirectories` → **source 模式**
|
|
584
|
+
- 用户提到 image tag / registry 路径(如 `<name>:<tag>`、`docker.io/...`、`harbor.../...`)→ **image 模式**
|
|
585
|
+
- 用户只说组件名,且该名指向**简单单镜像基础设施软件**(数据库、消息队列、缓存、对象存储、Web 服务器、反向代理/负载均衡、注册中心、密钥管理等类别下被广泛使用、有官方/社区维护镜像,且通常一个主容器即可形成最小可运行服务的项目)→ **image 模式**,默认镜像名 `<name>:latest`(再经 Iron Law 6 代理改写)。这里用你自己的通用知识判断,**不要**等清单或穷举匹配。
|
|
586
|
+
- 用户只说软件名,且该名指向**复杂现成软件套件 / 多服务发行版**(例如 Harbor、GitLab、监控/可观测性 stack、带内置数据库/缓存/worker/jobservice/registry/UI 的产品套件)→ **complex suite 模式**:先寻找或要求 `docker-compose` / compose profile(含 `rainbond_get_project_source_profile` 返回 `topologySource == "compose"` 的画像)、`rainbond.app.json`、官方部署描述符,或让用户显式确认一份完整计划;最后才是 Rainbond 应用市场模板(**仅当用户明确选择模板路径时**才用);在证据缺失前禁止创建组件。
|
|
587
|
+
|
|
588
|
+
**证据仲裁(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 画像路径,应用市场模板至多作为一句建议提及,不得安装。
|
|
589
|
+
- 用户只说组件名,且该名是项目专属或来历不明(如 `my-api`、`order-service`、`payment-svc` 等业务命名风格) → 信号不足,**这时才**问"用镜像还是源码?"
|
|
590
|
+
|
|
591
|
+
判断标准(principle 而非清单):
|
|
592
|
+
- 在你的知识里,这个名字是不是**一个有公开镜像、单主服务可运行的成熟基础设施软件**?是 → image。
|
|
593
|
+
- 这个名字是不是**一个产品套件**,通常由多个互相依赖的组件组成,且 service list / depends_on / env / storage / external_url / TLS 这些字段需要官方描述符才能可靠?是 → complex suite,先要证据或用户确认。
|
|
594
|
+
- 这个名字是不是**业务领域命名风格**(含动词、含组织名、含具体业务概念)?是 → 问。
|
|
595
|
+
- 介于两者之间不确定?**优先按 image 默认**(更常见的部署方式)并在报告里告知推断理由,邀请用户覆盖。
|
|
596
|
+
|
|
597
|
+
自动推断的结果必须在最终报告里说明,例如:"已按 image 模式创建 clickhouse 组件(推断依据:该名为公认的列式分析数据库)。如需改用源码请告知。"
|
|
598
|
+
对 complex suite 的报告必须说明停止原因和下一步选择,例如:"Harbor 是多组件套件;当前没有 compose/Helm/官方描述符、`rainbond.app.json` 或用户确认计划,因此我不会凭通用知识创建 registry/core/jobservice/database 等组件。请提供部署描述符,或显式确认使用某个 Rainbond 模板。"(注意:如果画像已返回 compose/manifest 证据,门槛即已满足,不要再报"缺证据",按证据仲裁直接进入对应部署路径。)
|
|
599
|
+
|
|
600
|
+
**禁止行为**:
|
|
601
|
+
- 用户给了 git_url 还问"用镜像还是源码?"(信号已经明确)
|
|
602
|
+
- 用户给了 image tag 还问"用镜像还是源码?"(信号已经明确)
|
|
603
|
+
- 对一个你的训练知识里明显是基础设施软件的名字(不管是否在某个示例清单里)问"用镜像还是源码?" —— Nginx、Redis、ClickHouse、Jaeger、Loki、OpenTelemetry Collector 都属于这一类,未来出现的新项目也会属于这一类,用判断不要用穷举
|
|
604
|
+
- 对 Harbor / GitLab / 监控 stack / 其他复杂套件,在没有 compose profile、`rainbond.app.json`、官方部署描述符或用户确认计划时,凭通用知识创建多个组件、依赖、env、存储或端口
|
|
605
|
+
- 已经拿到 compose / manifest 画像证据(门槛已满足)时,还以"找更可靠证据"为由去查模板库(`rainbond_query_local_app_models` / `rainbond_query_cloud_app_models`),或把找到的同名模板当默认路径——尤其用户已显式给了 Git URL 时(违反证据仲裁与 Iron Law 38)
|
|
606
|
+
|
|
607
|
+
**stateful 服务的持久化要求**:当推断结果是 image 模式 **且** 该服务属于 stateful 范畴(数据库 / 持久化消息队列 / 搜索引擎 / 时序库 / 对象存储 / 向量库 / 图库等 — 数据必须跨重启存活的任何服务),**必须**在 deploy 之前配好持久化。
|
|
608
|
+
|
|
609
|
+
**平台现实(fact)**:`rainbond_create_component_from_image` 和 `rainbond_create_component_from_source` 都不暴露 `extend_method` 参数,平台也没有 stateless→stateful 的转换工具。所以镜像/源码模式创建的组件**必然是 stateless**。不要尝试创建后再"改成 stateful",做不到。
|
|
610
|
+
|
|
611
|
+
**持久化方案**:
|
|
612
|
+
1. 用 `rainbond_manage_component_storage(operation=create_volume, volume_type=share-file, volume_path=<官方数据目录>)` 在服务的数据目录挂 RWX 共享文件存储(stateless 组件能挂)
|
|
613
|
+
2. 然后 `rainbond_operate_app(action=deploy)` — **先挂存储再 deploy**,顺序不能反
|
|
614
|
+
3. **禁止**用 `volume_type=local`(local 强制要求 stateful,平台会 HTTP 400 拒绝)
|
|
615
|
+
|
|
616
|
+
**需要 stateful + local volume(高 IOPS 数据库)的唯一路径**:通过 `rainbond_install_app_model` 从应用市场安装预配置的 stateful 模板。镜像/源码模式做不到这件事,不要假装能做。
|
|
617
|
+
|
|
618
|
+
具体的官方数据目录清单、`volume_type` 兼容矩阵、识别 stateful 服务的范畴边界详见 bootstrap skill 的 `modules/30-creation-rules.md § 5`。stateful 服务用 image 模式部署却没配持久化是真实回归 bug(pod 重启数据丢失),禁止以"模型不知道这个 service 是 stateful"或"工具不支持 extend_method"为由跳过持久化步骤。
|
|
619
|
+
38. **用户显式源码意图优先(禁止"先装模板再改主意手搓")**:当用户消息里**明确给出了 Git 仓库 URL**(或明确说"部署这个仓库 / 这个项目的源码"),本轮部署路径**锁定为源码 / compose 画像路径**。
|
|
620
|
+
- 应用市场模板(`rainbond_install_app_model` / 云市场版本)只能作为**建议提及**("该应用市场也有现成的 X 模板,需要的话可以改用"),在用户**明确选择**模板之前**禁止执行模板安装**。
|
|
621
|
+
- **禁止**这条真实反例链路:用户给了 GitHub URL → 模型先建应用装了云市场模板(`is_deploy=true`)→ 发现不对又放弃 → 另建应用手搓镜像组件 → 留下一个半装的废弃应用没清理。每一步都消耗用户授权、且制造垃圾资源。
|
|
622
|
+
- 如果策略切换确实发生(例如确认源码路径走不通、用户改主意要用模板),切换前**必须先清理废弃的半成品应用**(删掉上一条路径建出来的应用/组件),或在切换时**明确告知用户存在这个半成品并征求处理意见**,不允许默默留着。
|
|
623
|
+
- 与 Iron Law 14(delivery mode 切换必须用户确认)配套:14 管 source↔package↔image↔template 的策略切换需用户确认,38 管"用户已经显式给了源码意图时,模板不是默认路径、且切换必须清理残留"。
|
|
624
|
+
39. **轮次纪律:复用已知值,不重复无变化的调用**(与 Iron Law 35 的"内部 preflight 工具不要主动调"配套,35 管哪些工具不该调,39 管已拿到的值要复用):
|
|
625
|
+
- **复用创建返回的 `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 时才查)。
|
|
626
|
+
- **不重复调 `rainbond_get_current_user`**:同一 operation 复用 `context resolve` 已保存的企业、工作空间和集群上下文;只有上下文失效或用户明确切换目标时才重新解析。
|
|
627
|
+
- **同一 mutating 调用成功后禁止原样重复**:一个写工具用相同入参成功返回后,不要在同一轮再发一次相同调用"确认一下"——成功就是成功,要确认状态用读工具(`rainbond_get_component_summary` 等),不要重发写调用。
|
|
628
|
+
40. **对外访问地址必须引用工具返回的真实值,禁止按格式拼装。** 组件的对外访问地址是**事实信息**,权威来源是 `rainbond_get_component_detail` 或 `rainbond_get_component_summary` 返回的 `access_infos` 字段(都来自网关真实绑定)。只需状态和访问地址时优先调用轻量的 detail;只有异常组件确实需要端口、env、存储或事件证据时才调用 summary。
|
|
629
|
+
- 本轮已通过上述任一工具拿到真实地址 → 报告里引用 `access_infos` 的真实值。
|
|
630
|
+
- 本轮**未**通过上述工具拿到可用地址 → 最终报告必须写"请在控制台该组件的端口页查看对外访问地址",**禁止**按记忆或文档示例的 URL 格式(`<name>.<ip>.nip.io`、`<service>-<port>-<team>.<ip>.nip.io` 等)拼装一个地址当成真的。
|
|
631
|
+
- **禁止**把任何拼装/猜测出来的访问地址写进任何组件 env(如 `APP_WEB_URL` / `*_BASE_URL` / `*_PUBLIC_URL` 等)。需要把对外地址回填给某个组件时,同样只能用 `access_infos` 的真实值;拿不到真实值就停下来让用户在控制台确认后提供,不要先拼一个填进去。
|
|
632
|
+
- 真实事故:模型在没有任何工具返回访问地址的情况下,照文档示例格式拼出 `http://dify.<ip>.nip.io`,既写进最终报告又配进了组件 `APP_WEB_URL`,全是编造的。这是 Iron Law 违反。
|
|
633
|
+
41. **部署位置和访问地址必须分开。** `project.deployment_location_url` 是 Rainbond 控制台应用概览地址;仅在可信 Console base(`RAINBOND_URL` 或等价 session context)、`team_name`、`region_name` 和 `app_id` 全部已知时生成:
|
|
634
|
+
`<console_base>/#/team/<urlencoded-team>/region/<urlencoded-region>/apps/<urlencoded-app-id>/overview`。
|
|
635
|
+
生成时去掉 `console_base` 末尾 `/`,逐段 URL encode;任一值缺失就写 `null`,禁止从公网访问域名反推 Console host。`delivery_state.preferred_access_url` 仍按 Iron Law 40 只引用网关真实返回值,两者禁止混用。
|
|
636
|
+
|
|
637
|
+
## 主线流程
|
|
638
|
+
|
|
639
|
+
1. 读取当前项目目录的本地绑定和 manifest,解析 team / region / app / environment。
|
|
640
|
+
2. 如果 unlinked,执行 `rainbond-project-init`。
|
|
641
|
+
3. 如果 linked 但 topology 不存在,执行 `rainbond-fullstack-bootstrap`。
|
|
642
|
+
4. 如果 topology 已存在但 runtime 还没收敛,执行 `rainbond-fullstack-troubleshooter`。
|
|
643
|
+
5. 如果 runtime 已足够健康且剩余问题只是交付判断,执行 `rainbond-delivery-verifier`。
|
|
644
|
+
6. 如果用户明确要求开发到测试主线,且 source app 严格达到 `delivered`,才自动进入:
|
|
645
|
+
`rainbond-app-version-assistant -> testing app -> rainbond-delivery-verifier`
|
|
646
|
+
7. 最终返回一个 `AppAssistantResult`,顶层 `project` 仍然表示 source app。
|
|
647
|
+
|
|
648
|
+
## 深入子流程(deep-dive into specialized skills)
|
|
649
|
+
|
|
650
|
+
本 skill 的主线只承诺路由+顶层判断;具体的拓扑创建、排障、交付、版本中心等执行逻辑都写在专项 skill 里(`rainbond-fullstack-bootstrap`、`rainbond-fullstack-troubleshooter`、`rainbond-delivery-verifier`、`rainbond-app-version-assistant`、`rainbond-template-installer`)。当主线判断"现在需要进入某个专项阶段"时,必须显式把该 skill 的执行手册拉到当前会话上下文中,否则你只会看到本 skill 的顶层指引、看不到专项 skill 的详细规则。
|
|
651
|
+
|
|
652
|
+
### 触发时机
|
|
653
|
+
|
|
654
|
+
在主线流程进入每个专项阶段的**第一个动作之前**,调用对应的 `select_skill_<id>` 工具一次(同一个 skill 在同一次 run 内只需调一次,后续都已生效)。具体映射:
|
|
655
|
+
|
|
656
|
+
| 主线阶段 | 触发条件 | 必须先调的工具 |
|
|
657
|
+
|---------|---------|---------------|
|
|
658
|
+
| 步骤 3:topology 创建 | linked 但拓扑/组件不存在;或要从源码/镜像/包创建/补齐组件 | `select_skill_rainbond-fullstack-bootstrap` |
|
|
659
|
+
| 步骤 4:运行态排障 | 组件已存在但运行不健康;构建失败、CrashLoopBackOff、ImagePullBackOff 等 | `select_skill_rainbond-fullstack-troubleshooter` |
|
|
660
|
+
| 步骤 5:交付验收 | 运行态健康,剩下的问题是用户能否访问、URL 是否可达、文件是否落盘等 | `select_skill_rainbond-delivery-verifier` |
|
|
661
|
+
| 步骤 6:dev-to-test promotion | 已 `delivered`,用户要求创建快照 + 测试 app | `select_skill_rainbond-app-version-assistant` |
|
|
662
|
+
| 模板安装路径 | 用户要求安装本地/云端 Rainbond 应用模板到目标 app | `select_skill_rainbond-template-installer` |
|
|
663
|
+
|
|
664
|
+
### 调用语义
|
|
665
|
+
|
|
666
|
+
- `select_skill_<id>` 是当前会话的载入指令,不消耗 MCP 工具,无副作用,无需用户审批
|
|
667
|
+
- 调用后该 skill 的完整执行手册立即进入系统提示,后续动作必须严格按该 skill 的判断顺序、术语、输出契约执行
|
|
668
|
+
- 多个专项 skill 可以叠加加载(例如 bootstrap → 发现需要排障 → 再 `select_skill_rainbond-fullstack-troubleshooter`),新加载的 skill 在主题冲突时优先级更高
|
|
669
|
+
- 不能用调用 `select_skill_<id>` 来"探索这个 skill 是什么意思"——只在确认要进入对应阶段时调用
|
|
670
|
+
|
|
671
|
+
### 边界
|
|
672
|
+
|
|
673
|
+
- 顶层路由判断("用户的意图是不是部署/排障/交付")仍然由本 skill 负责,不要在专项 skill 加载之后回头改路由
|
|
674
|
+
- 工具行为约束(如本 skill 硬规则第 30 条"源码失败后必须先 query 不能直接重 create")即使在专项 skill 加载之后仍然有效,专项 skill 只是补充更细的操作规则
|
|
675
|
+
- `rainbond-project-init` 是 workspace 型 skill,只在 Claude/Codex CLI 等有本地项目目录的客户端有意义;在 Web 端 rainagent 中**不存在** `select_skill_rainbond-project-init`,主线遇到 unlinked 时直接停下来让用户在 UI 中绑定项目
|
|
676
|
+
|
|
677
|
+
## 停止条件
|
|
678
|
+
|
|
679
|
+
以下情况必须停住,不再自动往下:
|
|
680
|
+
|
|
681
|
+
- 项目未链接,且 init 还没有完成
|
|
682
|
+
- team / app 选择仍然有歧义
|
|
683
|
+
- source ref 无效
|
|
684
|
+
- 多组件源码检测需要显式策略选择
|
|
685
|
+
- MCP / 控制面后端异常
|
|
686
|
+
- `delivery-verifier` 结果只是 `delivered-but-needs-manual-validation`
|
|
687
|
+
- 进入 `code_or_build_handoff_needed`
|