draftgo-cli 3.0.55 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +112 -316
  2. package/package.json +5 -5
  3. package/resources/skill/SKILL.md +25 -24
  4. package/resources/skill/init/SKILL.md +5 -10
  5. package/resources/skill/manifest.json +2 -2
  6. package/resources/skill/references/aihub.md +10 -5
  7. package/resources/skill/references/chat-sdk.md +10 -0
  8. package/resources/skill/references/checkout.md +4 -4
  9. package/resources/skill/references/custom-services.md +65 -226
  10. package/resources/skill/references/data.md +3 -2
  11. package/resources/skill/references/frontend.md +96 -490
  12. package/resources/skill/references/mcp.md +39 -103
  13. package/resources/skill/references/runtime.md +3 -2
  14. package/resources/skill/story/SKILL.md +1 -2
  15. package/src/apiContractCache.js +112 -0
  16. package/src/cli.js +1 -21
  17. package/src/commandRegistry.js +6 -11
  18. package/src/commands/api.js +28 -8
  19. package/src/commands/check.js +1 -10
  20. package/src/commands/customService.js +2 -4
  21. package/src/commands/delete.js +23 -46
  22. package/src/commands/deploy.js +1 -1
  23. package/src/commands/help.js +16 -31
  24. package/src/commands/init.js +4 -10
  25. package/src/commands/listTargets.js +1 -1
  26. package/src/commands/local.js +2 -6
  27. package/src/commands/map.js +0 -11
  28. package/src/commands/status.js +1 -1
  29. package/src/commands/uninstall.js +3 -3
  30. package/src/commands/update.js +1 -1
  31. package/src/commands/verify.js +43 -21
  32. package/src/commands/{verifyUi.js → visualVerify.js} +28 -116
  33. package/src/commands/worklog.js +86 -0
  34. package/src/customServices.js +150 -33
  35. package/src/{localdev → localRuntime}/detect.js +1 -1
  36. package/src/{localdev → localRuntime}/mysqlClient.js +1 -1
  37. package/src/{localdev → localRuntime}/services.js +1 -1
  38. package/src/projectConfig.js +2 -0
  39. package/src/{installers/index.js → targets.js} +3 -5
  40. package/src/worklog.js +274 -0
  41. package/src/workspaceHealth.js +1 -1
  42. package/src/worktree/index.js +81 -51
  43. package/src/changelog.js +0 -276
  44. package/src/commands/changelog.js +0 -24
  45. package/src/commands/localDev.js +0 -9
  46. package/src/commands/sync.js +0 -46
  47. package/src/commands/task.js +0 -408
  48. package/src/commands/verifyUiCompat.js +0 -16
  49. /package/src/{localdev → localRuntime}/compose.js +0 -0
  50. /package/src/{localdev → localRuntime}/index.js +0 -0
@@ -1,19 +1,26 @@
1
1
  ---
2
-
3
2
  read_when: 编写、修改、调试或评审自定义服务时;使用服务 SDK、路由、事件、定时任务或服务依赖时
4
3
  ---
5
4
 
6
5
  # Go 自定义服务契约
7
6
 
8
- DraftGo 的新自定义服务使用 Go。服务代码是完整的 `package main`,可以使用标准库和 `go.mod` 中声明的第三方库。平台在保存或发布时编译服务、运行 `Register` 并保存触发器清单;执行时在独立子进程中调用选定 handler。
7
+ 自定义服务是完整的 Go `package main`。平台构建源码和 `go.mod`/`go.sum`,执行 `Register` 保存触发器清单,并在独立子进程中运行 handler。SDK 固定导入 `draftgo/sdk`;它由构建器注入,不写进 `require` 或 `replace`。
8
+
9
+ ## 开发流程
10
+
11
+ 完整正文使用:
9
12
 
10
- 平台 SDK 的固定导入路径是 `draftgo/sdk`。它是 DraftGo 构建器注入的本地 module,不从 GitHub 或其他网络仓库下载,也不要在服务的 `go.mod` 中自行添加或 `replace` 此依赖。
13
+ ```bash
14
+ draftgo checkout custom-services <id...>
15
+ draftgo commit custom-services <id...>
16
+ draftgo validate custom-services <id>
17
+ draftgo test custom-services <id> [--handler route:POST:/path]
18
+ draftgo publish custom-services <id...>
19
+ ```
11
20
 
12
- ## 索引
21
+ checkout 目录包含 `service.go`、`go.mod`、`go.sum`、`service.json` 及对应 base。commit 只保存共享 cloud draft;publish 才切换线上版本。定位、创建、权限和结构化元数据通过 MCP 实时 operation 完成,创建后取得 ID 再 checkout。
13
22
 
14
- - [最小服务](#最小服务)[本地资源](#本地资源)、[触发器](#触发器)
15
- - [平台 SDK](#平台-sdk)、[AI 平台 SDK](#ai-平台-sdk)
16
- - [权限与运行限制](#权限与运行限制)、[实时 API](#实时-api)、[验收清单](#验收清单)
23
+ 不同服务可并发处理;同一服务保持 commit -> validate -> test/publish 顺序。草稿 revision 是内容版本,`validated_revision` / `validated_hash` 是该版本的验证凭证。保存会清空凭证;测试和发布必须使用当前 revision。CLI 会复用有效凭证,不重复 commitcheckout 或 validate。
17
24
 
18
25
  ## 最小服务
19
26
 
@@ -23,275 +30,107 @@ package main
23
30
  import "draftgo/sdk"
24
31
 
25
32
  func Register(app *sdk.App) {
26
- app.Route("GET", "/health", health)
27
- app.On("order.paid", afterPaid)
28
- app.Schedule("0 9 * * 1-5", weekdayReport)
33
+ app.Route("GET", "/health", health)
34
+ app.On("order.paid", afterPaid)
35
+ app.Schedule("0 9 * * 1-5", weekdayReport)
29
36
  }
30
37
 
31
38
  func health(draftgo *sdk.Context) (any, error) {
32
- return draftgo.Respond(map[string]any{"ok": true}, 200, nil), nil
33
- }
34
-
35
- func afterPaid(draftgo *sdk.Context) (any, error) {
36
- draftgo.Log.Info("order paid event received")
37
- return nil, nil
39
+ return draftgo.Respond(map[string]any{"ok": true}, 200, nil), nil
38
40
  }
39
41
 
42
+ func afterPaid(draftgo *sdk.Context) (any, error) { return nil, nil }
40
43
  func weekdayReport(draftgo *sdk.Context) (any, error) { return nil, nil }
41
44
  ```
42
45
 
43
- `Register` 必须没有业务副作用。它只注册 handler;网络请求、写数据库、发通知等操作放在 handler 内。
44
-
45
- ## 资源读写
46
-
47
- 自定义服务是结构化远端资源,不使用 checkout/commit,也没有约定的本地镜像目录。先用
48
- `draftgo_resource_search` 定位服务,再用 `draftgo_api_search` / `draftgo_api_describe` 获取当前管理接口契约,
49
- 通过 `draftgo_api_call` 读取、创建或更新。Agent 可以在普通工作区文件中编写和检查 Go 源码,但不得把该文件
50
- 误当作远端事实来源;写入时按实时契约显式发送代码和元数据。
51
-
52
- 常见服务载荷字段如下,实际字段以 `draftgo_api_describe` 为准:
53
-
54
- ```json
55
- {
56
- "name": "order-service",
57
- "slug": "order-service",
58
- "mode": "mixed",
59
- "code": "package main\n\n// ...\n",
60
- "go_mod": "module example.com/order-service\n\ngo 1.26.0\n\nrequire github.com/google/uuid v1.6.0\n",
61
- "go_sum": ""
62
- }
63
- ```
64
-
65
- - 新服务使用 `mode=mixed`,允许同一个 `Register` 同时注册 route、event 和 scheduled。旧服务可继续使用单一 `route`、`event` 或 `scheduled` mode。
66
- - `go_mod` 和可选的 `go_sum` 随服务版本保存,并和代码一起通过实时管理 API 提交。
67
- - 新依赖应锁定明确版本。构建错误会在保存/发布时返回,不会替换当前有效清单。
46
+ `Register` 只注册 handler,不访问网络、数据库或通知系统。新服务使用 `mode=mixed`;第三方依赖锁定明确版本并写入 `go.mod`,可选校验和写入 `go.sum`。
68
47
 
69
48
  ## 触发器
70
49
 
71
50
  ### Route
72
51
 
73
- ```go
74
- func Register(app *sdk.App) {
75
- app.Route("POST", "/orders", createOrder)
76
- }
77
-
78
- func createOrder(draftgo *sdk.Context) (any, error) {
79
- body, _ := draftgo.Input["body"].(map[string]any)
80
- return draftgo.Respond(body, 201, nil), nil
81
- }
82
- ```
83
-
84
- `slug=commerce` 时地址为 `POST /api/x/commerce/orders`。Route 精确匹配,不支持 `/orders/{id}` 模板;ID 使用 query 或 body。
52
+ `app.Route("POST", "/orders", createOrder)` 在 `slug=commerce` 时对应 `POST /api/x/commerce/orders`。Route 精确匹配,不支持 `/orders/{id}` 模板;ID 使用 query 或 body。
85
53
 
86
- `draftgo.Input` 的 Route 字段:`method`、`headers`、`body`、`query_params`、`path_params`。当前身份通过 `draftgo.Auth.CurrentUser()` 获取,入站请求头通过 `draftgo.Headers.Get("Authorization")` 等读取。
54
+ 输入字段为 `method`、`headers`、`body`、`query_params`、`path_params`。身份由 `draftgo.Auth.CurrentUser()` 获取。普通 `draftgo.DB`、`Users` 等调用继承请求调用者权限;管理员创建服务、持有 SAT 或 `RequireAdmin` 都不会自动提升 SDK 调用。
87
55
 
88
- Route 默认以请求调用者身份访问 `draftgo.DB`、`draftgo.Users` 和其他平台能力。服务由管理员创建、拥有 `scripts:*` 管理权限,或在请求中收到 SAT,都不会让普通 SDK 调用自动提升;`draftgo.Auth.RequireAdmin()` 也只检查当前调用者。
89
-
90
- 可信服务需要管理员权限时,逐次显式使用 `draftgo.Admin.*`。这不是服务配置项,也不需要 `admin_access` 开关:调用 `Admin` 就是管理员调用声明。运行时为**这一次**平台 SDK 调用注入管理员身份,并把服务、版本、真实调用者、操作、资源和结果写进该次执行的审计日志;SAT、数据库连接和管理员凭据不会暴露给服务代码。
91
-
92
- ```go
93
- func catalog(draftgo *sdk.Context) (any, error) {
94
- // 继承调用者权限
95
- owned, err := draftgo.DB.Query("order", sdk.QueryOptions{})
96
- if err != nil { return nil, err }
97
-
98
- // 显式管理员权限;仅此调用提升
99
- internal, err := draftgo.Admin.DB.Query("internal_catalog", sdk.QueryOptions{})
100
- if err != nil { return nil, err }
101
-
102
- return draftgo.Respond(map[string]any{
103
- "orders": owned.Items,
104
- "catalog": internal.Items, // 生产代码应再按客户端可见字段组装
105
- }, 200, nil)
106
- }
107
- ```
108
-
109
- `draftgo.Admin` 提供与普通 SDK 对齐的 `DB`、`Users`、`Auth`、`Notify`、`HTTP`、`Cache`、`Config`、`AIHub`、`Knowledge`、`Memory` 能力。它等价于管理员在平台拥有的权限,不做资源级白名单;因此只能授予可信服务编辑者,并且 Route 返回值仍必须由代码负责脱敏。
56
+ 可信服务需要管理员能力时逐次显式调用 `draftgo.Admin.*`。它只提升该次 RPC,并审计服务、版本、真实调用者、操作、资源和结果;服务代码拿不到 SAT、数据库连接或管理员凭据。Route 返回值仍需自行脱敏。
110
57
 
111
58
  ### Event
112
59
 
113
- ```go
114
- app.On("user.registered", welcome)
115
-
116
- func welcome(draftgo *sdk.Context) (any, error) {
117
- payload, _ := draftgo.Input["payload"].(map[string]any)
118
- draftgo.Log.Info("registered user: " + fmt.Sprint(payload["user_id"]))
119
- return nil, nil
120
- }
121
- ```
122
-
123
- 事件异步且不阻塞原请求。事件输入含 `event`、`timestamp`、`payload`。
124
-
125
- 事件 `payload` 含 `user_id` 或 `actor_user_id` 且该用户仍存在时,handler 继承该用户身份;无法解析用户时才以系统身份执行。事件服务应把事件数据视为业务输入,而不是把它当成绕过资源权限的通道。
60
+ `app.On("user.registered", welcome)` 异步执行,不阻塞原请求。输入含 `event`、`timestamp`、`payload`。payload 中可解析的 `user_id` / `actor_user_id` 会作为继承身份;无法解析时才使用系统身份。
126
61
 
127
62
  ### Scheduled
128
63
 
129
- ```go
130
- app.Schedule("0 2 * * *", cleanup)
131
- ```
132
-
133
- cron 使用五字段表达式,也支持 `interval:5m`。定时 handler 的 `draftgo.Input` 为空对象。
64
+ `app.Schedule("0 2 * * *", cleanup)` 使用五字段 cron,也支持 `interval:5m`。定时任务没有调用者,以系统身份执行;仅可信编辑者可维护,并应限制写入范围、记录业务日志。
134
65
 
135
- 定时任务没有调用者,会以系统身份执行。因此它只能由可信编辑者维护,写入范围应限制在明确的数据类型,并在 handler 中记录可审计的业务日志。
66
+ ## SDK
136
67
 
137
- ## 平台 SDK
68
+ 所有平台访问通过受控 RPC 返回主服务,不自行读取宿主环境变量、数据库连接或 token。
138
69
 
139
- 所有资源访问经受控 RPC 返回 Go 主服务。不要自行读取数据库连接、服务 token 或宿主机环境变量。
70
+ | 入口 | 核心能力 |
71
+ |---|---|
72
+ | `draftgo.DB` | Create/CreateMany/Get/Update/UpdateMany/Delete/Query |
73
+ | `draftgo.Users` | Get/List/Update |
74
+ | `draftgo.Auth` | RequireLogin/RequireAdmin/RequireRole/CurrentUser |
75
+ | `draftgo.Notify` | 站内通知 |
76
+ | `draftgo.HTTP` | Get/Post/Put/Patch/Delete |
77
+ | `draftgo.Cache` / `Config` | 缓存与系统配置 |
78
+ | `draftgo.AIHub` | Agent/模型推理、图片、Embedding、AI 资产与运行记录 |
79
+ | `draftgo.Knowledge` | 知识库、文档、Chunk、上传、检索和重建 |
80
+ | `draftgo.Memory` | 长期记忆与全局检索配置 |
81
+
82
+ 常用示例:
140
83
 
141
84
  ```go
142
- record, err := draftgo.DB.Create("order", map[string]any{"title": "DraftGo"})
143
85
  records, err := draftgo.DB.Query("order", sdk.QueryOptions{
144
- Filters: map[string]any{"status": "paid"},
145
- Page: 1, PageSize: 20, OrderBy: "id", Order: "desc",
86
+ Filters: map[string]any{"status": "paid"}, Page: 1, PageSize: 20,
87
+ })
88
+ reply, err := draftgo.AIHub.Chat(draftgo.Context(), sdk.AIChatRequest{
89
+ AgentID: 12, Message: "总结订单",
146
90
  })
147
-
148
- user, err := draftgo.Users.Get(12)
149
- err = draftgo.Auth.RequireLogin()
150
- err = draftgo.Notify.Send(12, "完成", "订单已创建", "info")
151
-
152
- cached, err := draftgo.Cache.Get("daily-report")
153
- err = draftgo.Cache.Set("daily-report", map[string]any{"ok": true}, time.Hour)
154
-
155
- value, err := draftgo.Config.Get("feature_flag", false)
156
91
  response, err := draftgo.HTTP.Get(draftgo.Context(), "https://api.example.com/health", nil, 10*time.Second)
157
-
158
- reply, err := draftgo.AIHub.Chat(draftgo.Context(), sdk.AIChatRequest{AgentID: 12, Message: "总结订单"})
159
- draftgo.Log.Info("service completed")
160
92
  ```
161
93
 
162
- `draftgo.DB` 支持 `Create`、`CreateMany`、`Get`、`Update`、`UpdateMany`、`Delete`、`Query`。`Query` 返回 `sdk.QueryResult{Items, Total, Page, PageSize}`。
94
+ HTTP host 可由 `config.http_allowed_hosts` 限制;timeout 最终为 1-30 秒,响应体最大 5 MB。日志每次执行最多 500 条、单条 4096 字符,不记录 token、Cookie、密码或完整个人信息。
163
95
 
164
- `draftgo.Users` 支持 `Get`、`List`、`Update`。`draftgo.Auth` 支持 `RequireLogin`、`RequireAdmin`、`RequireRole`、`CurrentUser`。
96
+ ### AI 权限
165
97
 
166
- `draftgo.HTTP` 支持 `Get`、`Post`、`Put`、`Patch`、`Delete`;响应为 `sdk.HTTPResponse{StatusCode, Headers, Data}`。服务可使用 `config.http_allowed_hosts` 限制出站目标;HTTP timeout 最终限制为 1-30 秒,响应体最大 5 MB。
98
+ 普通 AIHub/Knowledge/Memory 继承用户身份并经过 `aihub:*` 等权限。`draftgo.Admin.AIHub`、`Admin.Knowledge`、`Admin.Memory` 与普通入口同构,但逐次以管理员执行并审计。
167
99
 
168
- ## AI 平台 SDK
169
-
170
- | 入口 | 能力 |
171
- |---|---|
172
- | `draftgo.AIHub` | Agent/模型推理、图片、Embedding、Agent/Prompt/Skill/MCP 资产 CRUD、供应商、模型路由、Skill 安装与版本、运行记录 |
173
- | `draftgo.Knowledge` | 知识库、文档、Chunk CRUD,文档上传、检索、重建索引 |
174
- | `draftgo.Memory` | 长期记忆 CRUD 与全局检索配置 |
175
-
176
- 普通入口继承调用用户身份,继续经过 `aihub:read/create/update/delete/execute/invoke` 等平台权限检查。`draftgo.Admin.AIHub`、`draftgo.Admin.Knowledge`、`draftgo.Admin.Memory` 提供同构接口,每次调用以管理员身份执行并进入自定义服务执行审计。
177
-
178
- ### 推理与配置
179
-
180
- ```go
181
- reply, err := draftgo.AIHub.Chat(draftgo.Context(), sdk.AIChatRequest{
182
- AgentID: 12,
183
- Message: "总结订单",
184
- })
185
-
186
- direct, err := draftgo.AIHub.Chat(draftgo.Context(), sdk.AIChatRequest{
187
- Model: "gpt-4.1-mini",
188
- Messages: []map[string]any{{"role": "user", "content": "hello"}},
189
- })
190
-
191
- vectors, err := draftgo.AIHub.Embeddings(draftgo.Context(), sdk.AIEmbeddingRequest{
192
- Model: "text-embedding-3-small",
193
- Input: []string{"first document", "second document"},
194
- })
195
- ```
196
-
197
- `GenerateImage` 支持 Agent 和直接模型两种调用。普通入口的推理必须在服务 `config.aihub` 中显式开启:
100
+ 普通推理还必须在服务配置中启用:
198
101
 
199
102
  ```json
200
103
  {
201
104
  "aihub": {
202
105
  "enabled": true,
203
- "allowed_agents": [12, 18],
106
+ "allowed_agents": [12],
204
107
  "allow_direct_model_call": true,
205
- "allowed_models": ["gpt-4.1-mini", "text-embedding-3-small"],
108
+ "allowed_models": ["gpt-4.1-mini"],
206
109
  "allow_images": true
207
110
  }
208
111
  }
209
112
  ```
210
113
 
211
- 空白名单表示不额外限制,但用户权限、Agent 调用权限和模型外部调用策略仍然生效。Agent 预览与后续新增的 `/api/v1/*` 推理端点也使用同一组白名单策略。
212
-
213
- ### AI 资产、Skill 与 MCP
214
-
215
- Agent、Prompt、Skill、MCP 使用统一资产 CRUD,通过 `type` 区分:
216
-
217
- ```go
218
- skills, err := draftgo.AIHub.ListAssets(draftgo.Context(), map[string]any{
219
- "type": "skill", "page": 1, "page_size": 50,
220
- })
221
-
222
- mcp, err := draftgo.AIHub.CreateAsset(draftgo.Context(), map[string]any{
223
- "type": "mcp", "name": "internal-tools",
224
- "data": map[string]any{"transport": "http", "url": "https://mcp.example.com"},
225
- "status": 1,
226
- })
227
-
228
- tools, err := draftgo.AIHub.DiscoverMCPTools(draftgo.Context(), map[string]any{
229
- "transport": "http", "url": "https://mcp.example.com",
230
- })
231
- ```
232
-
233
- 资产方法包括 `ListAssets/GetAsset/CreateAsset/UpdateAsset/UpdateAssets/DeleteAsset`、`AgentReadiness/PublishAgent`、`DiscoverMCPTools`、`InstallSkill/InstallSkillArchive/ListSkillVersions/RollbackSkill`。供应商使用 `ListProviders/GetProvider/CreateProvider/UpdateProvider/DeleteProvider/DiscoverProvider/SyncProvider`;模型和路由使用 `ListModels/GetModel/CreateModel/UpdateModel/DeleteModel/ProbeModel/UpdateModelRoute/DeleteModelRoute`;运行记录使用 `ListRuns/GetRun/DeleteRuns`。
234
-
235
- ### 知识库与记忆
236
-
237
- ```go
238
- base, err := draftgo.Knowledge.Create(draftgo.Context(), map[string]any{
239
- "name": "产品手册", "embedding_model_id": 7,
240
- })
241
-
242
- document, err := draftgo.Knowledge.UploadDocument(draftgo.Context(), baseID,
243
- sdk.KnowledgeDocumentUpload{
244
- Filename: "manual.pdf", MIMEType: "application/pdf", Content: pdfBytes,
245
- Metadata: map[string]any{"product": "DraftGo"},
246
- })
247
-
248
- matches, err := draftgo.Knowledge.Retrieve(draftgo.Context(), baseID, map[string]any{
249
- "query": "如何配置模型供应商?", "mode": "hybrid", "top_k": 6,
250
- })
251
-
252
- memory, err := draftgo.Memory.Create(draftgo.Context(), map[string]any{
253
- "scope": "user_agent", "user_id": 42, "agent_id": 12,
254
- "content": "用户偏好简洁的中文回答", "importance": 0.8,
255
- })
256
- ```
257
-
258
- `Knowledge` 还提供知识库 `List/Get/Update/Delete`、文档 `ListDocuments/GetDocument/UpdateDocument/DeleteDocument/ReindexDocument`、Chunk `ListChunks/UpdateChunk` 以及 `RebuildIndex`。文档上传受 8 MiB 限制。`Memory` 提供 `List/Get/Create/Update/Delete`,全局配置使用 `draftgo.Memory.GetConfig` 和 `draftgo.Memory.UpdateConfig`。
259
-
260
- ### 扩展入口
261
-
262
- typed helper 尚未覆盖新端点时,使用 `AIHub.Request`:
263
-
264
- ```go
265
- value, err := draftgo.AIHub.Request(draftgo.Context(), sdk.AIRequest{
266
- Method: "GET",
267
- Path: "/api/aihub/types",
268
- })
269
- ```
270
-
271
- `Request` 只接受 `/api/aihub`、`/api/agents`、`/api/v1`、`/api/images`、`/api/knowledge-bases`、`/api/memories`、`/api/skills` 路径;禁止外部 URL、路径穿越和在 `Path` 中拼 query。身份、权限、推理开关与审计规则和 typed helper 相同。
272
-
273
- 日志每次执行最多 500 条、单条最多 4096 字符。不要记录 token、Cookie、密码或完整个人信息。
114
+ 空白名单表示不额外限制,不会绕过用户权限、Agent 调用权限或模型外部调用策略。typed helper 未覆盖的新端点可使用 `AIHub.Request`,但 path 只能位于平台允许的 AI/Knowledge/Memory 前缀,不能传外部 URL、路径穿越或内嵌 query。
274
115
 
275
- ## 权限与运行限制
116
+ ## 权限与运行
276
117
 
277
- - `scripts:read/create/update/delete/execute` 控制可信人员管理服务。
278
- - Route 调用者仍由服务 `permission` 与 `config.route_security` 控制;管理权限不绕过 Route 调用权限。
279
- - Route 的普通 SDK 数据访问继承调用者权限;不要把“管理员创建服务”误写成自动提升。只有显式 `draftgo.Admin.*` 调用才以管理员执行并记录审计;定时任务和无可解析用户的事件是系统身份例外。
280
- - `config.timeout`、`max_concurrency`、`queue_timeout_ms` 适用于服务执行。Route 饱和时返回 HTTP 429。
281
- - Go 服务以独立进程运行,超时会终止该进程;它不是为不可信多租户代码准备的安全沙箱。只向可信编辑者授予服务编辑权限。
282
- - 每个保存版本按源码、依赖、SDK 和 Runner 协议生成不可变构建键。代码或依赖变更会生成新构建产物;旧版本可通过现有版本恢复接口重新激活。
118
+ - `scripts:read/create/update/delete/execute` 控制服务管理。
119
+ - Route 仍受服务 `permission` 与 `config.route_security` 控制。
120
+ - 只有显式 `draftgo.Admin.*`、定时任务和无可解析用户的事件是提升身份例外。
121
+ - `config.timeout`、`max_concurrency`、`queue_timeout_ms` 控制执行;Route 饱和返回 429。
122
+ - 超时会终止独立子进程。运行器不是不可信多租户安全沙箱,只授予可信编辑者服务权限。
123
+ - 构建键覆盖源码、依赖、SDK 和 Runner 协议;有效验证凭证绑定该键,任一部分变化都必须重新验证。
283
124
 
284
125
  ## 实时 API
285
126
 
286
- 服务管理接口使用标准 `{code, data, message}` 信封并受 `scripts:*` 权限控制。具体 operation、参数、请求体、响应和风险必须通过 MCP `draftgo_api_search` `draftgo_api_describe` 获取后再调用,不维护静态路径表。
127
+ 管理接口使用标准 `{code,data,message}` 信封。未知 operation search,首次使用或 registry revision 变化时 describe;完整服务正文不进入 MCP 参数。
287
128
 
288
- 有效 `app.Route` 会以实际 method、`/api/x/{slug}/{path}`、权限、风险和输入 schema 动态加入同一 MCP registry;搜索 `resource_type=custom_scripts` 或 `module=scripts_dynamic` 后描述并调用。运行时 Route 返回 handler 自定义响应,不强制使用管理 API 信封;精确匹配、调用身份和运行限制仍以本文件的 Route 与权限章节为准。
129
+ 有效 `app.Route` 会按实际 method 和 `/api/x/{slug}/{path}` 动态加入 MCP registry。运行时响应由 handler 决定,不强制管理 API 信封;精确匹配、身份继承和执行限制仍以本文件为准。
289
130
 
290
- ## 验收清单
131
+ ## 完成条件
291
132
 
292
- - [ ] `package main` 且实现 `Register(app *sdk.App)`。
293
- - [ ] 服务使用 `mode=mixed`,第三方库写入 `go_mod`。
294
- - [ ] 路由使用 `app.Route`,事件使用 `app.On`,定时任务使用 `app.Schedule`。
295
- - [ ] handler 返回 `(any, error)`,需要状态码时使用 `draftgo.Respond`。
296
- - [ ] Route 显式设置 `permission` 与 `route_security`。
297
- - [ ] 保存或发布后请求无副作用 GET Route,并记录状态码和响应作为验收证据。
133
+ - `package main` 且实现无业务副作用的 `Register(app *sdk.App)`。
134
+ - trigger handler 签名正确,第三方依赖已锁定。
135
+ - Route 权限、管理员调用和返回脱敏符合真实调用者范围。
136
+ - `draftgo validate` 通过;需要运行行为证据时执行相关 `draftgo test`。发布仅在用户任务包含发布时进行。
@@ -152,8 +152,9 @@ await App.patch(`db/order/batch`, [
152
152
 
153
153
  ## db_meta 实时契约
154
154
 
155
- db_meta 是结构化远端资源,不 checkout,也不生成本地 `index.json`。开发前先通过 MCP
156
- `draftgo_api_search` / `draftgo_api_describe` 确认接口,再用 `draftgo_api_call` 查询目标 type 和 schema。
155
+ db_meta 是结构化远端资源,不 checkout,也不生成本地索引。未知 operation 才通过 MCP
156
+ `draftgo_api_search` 定位;首次使用或 registry revision 变化时 `draftgo_api_describe`,再用
157
+ `draftgo_api_call` 查询目标 type 和 schema。
157
158
  典型返回条目如下:
158
159
 
159
160
  ```json