Files
memind/docs/help-code02.md
T
john 4c1890f344
Memind CI / Test, build, and release guards (pull_request) Successful in 2m22s
fix(ci): remove trailing whitespace from phase 5 docs
2026-07-25 09:27:40 +08:00

383 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Help Code02Code Run / Page Data Dev 的 memindadm 运行时策略
> 文档版本:2026-07-23<br>
> 状态:方案设计(未实施)<br>
> 前置:[help-code01.md](./help-code01.md)Aider 补充 Page Data 开发兜底)<br>
> 关联:[memindadm-goose-gateway-design.md](./memindadm-goose-gateway-design.md)
---
## 1. 为什么要做 Phase 1.5
Phase 1 用 **env + VITE_ 构建期变量** 控制 code run 与 `page_data_dev` autodetect。这在 dev/staging 可用,但对「用户经常页面失败、插入失败」的运营场景不够:
| 问题 | env/VITE 的局限 |
|------|----------------|
| 改开关要 rebuild H5 | `VITE_*` 打进 bundlememindadm 点了不生效 |
| 改开关要 SSH 改 `.env` | 103 Portal / worker 两套 env,易不一致 |
| 无法按用户即时灰度 | 白名单改 env 无审计、无 UI |
| 与现有 adm 能力分裂 | aider 能力已在 `h5_capability_grants`,策略却在 env |
**目标:****「谁、哪种 task、是否 page_data_dev autodetect」** 迁入 memindadm**部署拓扑**worker 是否 spawn Aider)继续留 env。
---
## 2. 配置分层(硬边界)
```mermaid
flowchart TB
subgraph adm ["memindadm 运行时策略(DB"]
P1[codeRun.enabled]
P2[userAllowlist / roleAllowlist]
P3[taskTypeAllowlist 含 page_data_dev]
P4[pageDataDev.autodetect]
P5[requireValidation]
P6[generalCodeAutodetect]
end
subgraph env ["部署 env(不改或只读 override"]
E1[MEMIND_TOOL_GATEWAY_ENABLED]
E2[AIDER_BIN / OPENHANDS_BIN]
E3[worker 并发 / 超时 / guard]
E4[MEMIND_AGENT_RUN_* 紧急 override]
end
subgraph cap ["已有用户能力(DB"]
C1[h5_capability_grants: aider/openhands]
C2[h5_llm_executor_bindings]
end
adm --> Portal[agent-run-routes 校验]
adm --> Auth["/auth/status → H5"]
cap --> Portal
env --> Worker[agent-run-worker]
Portal --> Worker
```
### 2.1 进 memindadm 的项
| 原 env / VITE | adm 字段 | 说明 |
|---------------|----------|------|
| `MEMIND_AGENT_CODE_RUNS_ENABLED` | `codeRun.enabled` | 后端是否接受 `tool_mode=code` |
| `MEMIND_AGENT_CODE_RUNS_USER_IDS` | `codeRun.userAllowlist` | 空 = 不限制(enabled 时) |
| `MEMIND_AGENT_CODE_RUN_TASK_TYPES` | `codeRun.taskTypeAllowlist` | 含 `page_data_dev``h5_chat_code_task` |
| `MEMIND_AGENT_CODE_RUNS_REQUIRE_VALIDATION` | `codeRun.requireValidation` | 是否强制 receipt |
| `VITE_AGENT_CODE_RUNS_ENABLED` | `codeRun.clientEnabled` | H5 是否展示/走 code 路径 |
| `VITE_AGENT_CODE_RUNS_AUTODETECT` | `codeRun.generalAutodetect` | 通用代码语义 autodetect |
| `VITE_AGENT_PAGE_DATA_DEV_AUTODETECT` | `pageDataDev.autodetect` | Page Data 修 bug 专用 autodetect |
### 2.2 继续留 env 的项
| env | 原因 |
|-----|------|
| `MEMIND_TOOL_GATEWAY_ENABLED` | worker 进程级;Portal 与 worker 故意不同值 |
| `MEMIND_TOOL_GATEWAY_DEFAULT_EXECUTOR` | 机器上装的是 aider 还是 openhands |
| `MEMIND_AGENT_RUN_QUEUE_CONCURRENCY` 等 | SLO / guard / LaunchAgent |
| `MEMIND_AGENT_CODE_RUNS_*`(可选) | **紧急 override**`MEMIND_CODE_RUN_POLICY_SOURCE=env` 时强制 env 优先 |
---
## 3. 数据模型
### 3.1 表:`h5_agent_code_run_config`
`h5_skill_runtime_config``h5_image_make_admin_config` 同模式:`config_scope='global'` 单行 JSON。
```sql
CREATE TABLE IF NOT EXISTS h5_agent_code_run_config (
config_scope VARCHAR(32) PRIMARY KEY,
config_json JSON NOT NULL,
updated_by CHAR(36) NULL,
updated_at BIGINT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### 3.2 默认 JSON Schema
```json
{
"codeRun": {
"enabled": false,
"clientEnabled": false,
"generalAutodetect": false,
"requireValidation": true,
"userAllowlist": [],
"taskTypeAllowlist": [
"page_data_dev",
"h5_chat_code_task",
"page_edit_code_task"
]
},
"pageDataDev": {
"autodetect": false
},
"meta": {
"notes": ""
}
}
```
### 3.3 生效优先级(与 Memory V2 adm 一致)
参考 `memory-v2-admin-config.mjs``FIELD_SPECS + env override` 模式:
```text
1. 若 MEMIND_CODE_RUN_POLICY_SOURCE=env → 仅读 env(紧急回滚)
2. 否则读 h5_agent_code_run_configadmin-db
3. 若表为空且 MEMIND_AGENT_CODE_RUNS_ENABLED=1 → source=env-migration(兼容旧部署)
4. 否则 default(全 falsefail closed
```
### 3.4 用户级能力(不重复造表)
以下 **仍用现有表**adm「Code Run 策略」页只读展示 + 链到用户能力编辑:
- `h5_capability_grants``aider` / `openhands`
- `h5_llm_executor_bindings`Aider 模型绑定
- `h5_user_policies``code_delegate_executor``code_task_routing`
**完整放行条件(与 today 相同,只是策略来源改为 DB):**
```text
codeRun.enabled (adm)
AND user ∈ allowlist(若配置)
AND taskType ∈ taskTypeAllowlist
AND capabilities.aider(用户 grant
AND executor binding 可用
AND(若 requireValidationmessage 含 validation metadata
AND toolGateway.enabledenvworker 侧)
```
---
## 4. 服务模块:`agent-code-run-admin-config.mjs`
建议新建,API 对齐 `skill-runtime-admin-config.mjs`
| 方法 | 用途 |
|------|------|
| `getAdminConfig()` | memindadm 编辑页 |
| `updateAdminConfig(patch, { updatedBy })` | 保存 + 审计 |
| `getRuntimeState()` | adm 运行时预览 |
| `getEffectivePolicy({ userId })` | Portal 校验用 |
| `getPublicClientPolicy({ userId })` | `/auth/status` 下发 H5 |
### 4.1 `getEffectivePolicy` 返回示例
```json
{
"source": "admin-db",
"updatedAt": 1753276800000,
"enabled": true,
"userAllowed": true,
"taskTypes": ["page_data_dev", "h5_chat_code_task", "page_edit_code_task"],
"requireValidation": true,
"pageDataDevAutodetect": true,
"generalAutodetect": false
}
```
### 4.2 `getPublicClientPolicy` 返回示例(按用户过滤后)
```json
{
"codeRun": {
"enabled": true,
"pageDataDevAutodetect": true,
"generalAutodetect": false
}
}
```
未登录或用户不在 allowlist 时:`codeRun.enabled=false`(或不返回该块)。
---
## 5. HTTP API
### 5.1 memindadm`admin-routes.mjs`
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/admin/agent-code-run/config` | 读配置 + source + updatedBy |
| PUT/PATCH | `/api/admin/agent-code-run/config` | 更新 |
| GET | `/api/admin/agent-code-run/runtime` | 有效策略 + env 覆盖状态 + worker 只读摘要 |
Worker 摘要可代理现有 `/api/runtime/status``toolRuntime.codeRunPolicy``queue`**只读**,不在 adm 改 worker env)。
### 5.2 Portal 用户面
**扩展 `GET /auth/status`**(已登录用户):
```json
{
"authenticated": true,
"user": { "...": "..." },
"capabilities": { "aider": true, "...": "..." },
"skillRuntime": { "...": "..." },
"agentCodeRun": {
"enabled": true,
"pageDataDevAutodetect": true,
"generalAutodetect": false
}
}
```
**扩展 `POST /api/agent/runs` 校验:**`getEffectivePolicy(userId)` 读,不再只读 `process.env.MEMIND_AGENT_CODE_RUNS_*`
### 5.3 只读运维
`GET /api/runtime/status` 增加:
```json
{
"toolRuntime": {
"codeRunPolicy": {
"source": "admin-db",
"enabled": true,
"userAllowlist": [],
"taskTypeAllowlist": ["page_data_dev", "..."],
"requireValidation": true,
"pageDataDevAutodetect": true,
"envOverrideActive": false
}
}
}
```
---
## 6. 前端改造(去掉 VITE_ 硬依赖)
### 6.1 `src/utils/agentRunMode.ts`
```typescript
// 优先级:runtime policy/auth/status> VITE_dev fallback
let runtimePolicy: AgentCodeRunClientPolicy | null = null;
export function applyAgentCodeRunClientPolicy(policy: AgentCodeRunClientPolicy | null) {
runtimePolicy = policy;
}
function clientCodeRunsEnabled(): boolean {
if (runtimePolicy?.codeRun?.enabled != null) return runtimePolicy.codeRun.enabled;
return agentCodeRunsEnabled; // VITE fallback
}
function clientPageDataDevAutodetect(): boolean {
if (runtimePolicy?.codeRun?.pageDataDevAutodetect != null) {
return runtimePolicy.codeRun.pageDataDevAutodetect;
}
return agentPageDataDevAutodetectEnabled;
}
```
### 6.2 注入时机
在现有 `/auth/status` 加载处(如 `src/api/client.ts` 或 auth hook):
```typescript
const status = await fetchAuthStatus();
applyAgentCodeRunClientPolicy(status.agentCodeRun ?? null);
```
**效果:** memindadm 打开 `pageDataDev.autodetect` 后,用户刷新页面即生效,**无需 rebuild H5**。
---
## 7. memindadm UIOps 后台)
建议菜单位置:**系统 / Agent 运行时 → Code Run & Page Data Dev**
| 控件 | 类型 | 说明 |
|------|------|------|
| Code Run 总开关 | toggle | `codeRun.enabled` |
| H5 客户端启用 | toggle | `codeRun.clientEnabled` |
| Page Data Dev Autodetect | toggle | `pageDataDev.autodetect` |
| 通用 Code Autodetect | toggle | `codeRun.generalAutodetect`(默认关) |
| 强制 Validation | toggle | `codeRun.requireValidation` |
| 用户白名单 | multi-select UUID | 空 = 全部(enabled 时) |
| Task Types | checkbox list | 至少含 `page_data_dev` |
| 当前 Worker 状态 | read-only | 来自 `/runtime/status` |
| Env Override 警告 | banner | `MEMIND_CODE_RUN_POLICY_SOURCE=env` 时显示 |
**保存时:**`updated_by` + `updated_at`;可选写 admin audit log(与 image-make 一致)。
---
## 8. 迁移与兼容
### 8.1 首次上线
1. 建表 `h5_agent_code_run_config`,默认全 `false`
2. 部署 `agent-code-run-admin-config.mjs` + admin API
3. **迁移脚本**(可选):若 env 已开启,import 到 DB 并提示改 `POLICY_SOURCE=admin`
```bash
node scripts/migrate-agent-code-run-config-from-env.mjs --dry-run
node scripts/migrate-agent-code-run-config-from-env.mjs --apply
```
### 8.2 回滚
| 场景 | 操作 |
|------|------|
| adm 配错了 | memindadm 关 `codeRun.enabled` |
| 紧急全站关闭 | `MEMIND_CODE_RUN_POLICY_SOURCE=env` + unset `MEMIND_AGENT_CODE_RUNS_ENABLED` |
| worker 异常 | LaunchAgent 停 worker(现有 runbook),与 adm 无关 |
### 8.3 与 help-code01 Phase 的关系
| Phase | 内容 | 配置来源 |
|-------|------|----------|
| Phase 1 ✅ | `page_data_dev` 意图 + autodetect 逻辑 | env/VITE |
| **Phase 1.5** | adm 运行时策略 + `/auth/status` | **DB + adm UI** |
| Phase 2 | verify → Aider dev loop 脚本 | 脚本 + adm 开关 |
---
## 9. 实施清单(Phase 1.5
- [x] `agent-code-run-admin-config.mjs` + 单测
- [x] `admin-routes.mjs``/agent-code-run/config``/runtime`
- [x] `server.mjs``/auth/status` 增加 `agentCodeRun`
- [x] `agent-run-routes.mjs`:改用 `getEffectivePolicy(userId)`
- [x] `agentRunMode.ts`runtime policy 优先于 VITE_
- [x] Ops UI 页面(表单 + JSON 高级编辑:`/ops/admin/agent-code-run`
- [x] `migrate-agent-code-run-config-from-env.mjs`
- [x] 更新 `docs/agent-run-worker-rollout-runbook.md`
- [x] `.env.example` 增加 `MEMIND_CODE_RUN_POLICY_SOURCE`
- [x] verify`agent-code-run-admin-config.test.mjs` + 扩展 `chat-agent-run-gate.test.mjs`
---
## 10. 安全与审计
1. **仅 admin 可写** — 复用 `requireAdmin`
2. **默认 fail closed** — 新环境 adm 配置为空 = 全关
3. **双闸门保留** — adm 开 + 用户 `aider` grant + worker gateway env
4. **审计字段**`updated_by``updated_at`;重要变更写 admin audit
5. **生产建议** — 先 `userAllowlist` 小范围开 `page_data_dev`,再扩 `generalAutodetect`
---
## 11. 相关文件索引
| 类型 | 路径 |
|------|------|
| 方案总览 | `docs/help-code01.md` |
| Goose 网关规划 | `docs/memindadm-goose-gateway-design.md` |
| 可复用 adm 模式 | `skill-runtime-admin-config.mjs` |
| env↔adm 映射先例 | `memory-v2-admin-config.mjs` |
| 后端 code run 门禁 | `agent-run-routes.mjs` |
| 前端 autodetect | `src/utils/agentRunMode.ts` |
| 运行时只读 | `server.mjs``runtimeCodeRunPolicyStatus()` |
| Worker runbook | `docs/agent-run-worker-rollout-runbook.md` |
---
## 12. 一句话总结
**memindadm 管「策略」(谁、哪种 task、是否 page_data_dev);env 管「部署」(worker 是否 spawn Aider);H5 从 `/auth/status` 读运行时策略,不再依赖 rebuild VITE_。**