merge: feature/page-data-dev-aider into main

Bring in Page Data Aider dev loop, adm code-run policy UI, and customer order demo.
Keep system disclosure policy and agent code-run admin wiring side by side.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-24 14:42:25 +08:00
39 changed files with 3295 additions and 47 deletions
+41
View File
@@ -37,6 +37,47 @@ runtime-slo-report.ok=true
runtime-slo-report.failures=[]
```
## Admin DB Policy (Phase 1.5)
Code-run **user/taskType/client toggles** can be managed in memindadm instead of rebuilding H5 for every change.
| Layer | Controls |
|-------|----------|
| **memindadm** (`h5_agent_code_run_config`) | `codeRun.enabled`, `clientEnabled`, allowlists, `pageDataDev.autodetect`, `generalAutodetect`, `requireValidation` |
| **Portal env** | `MEMIND_TOOL_GATEWAY_ENABLED`, worker queue topology, emergency override via `MEMIND_CODE_RUN_POLICY_SOURCE=env` |
| **H5 runtime** | `/auth/status.agentCodeRun` → client autodetect without `VITE_*` rebuild |
Admin API (memind_adm `:8082`):
```text
GET/PATCH /admin-api/agent-code-run/config
GET /admin-api/agent-code-run/runtime
```
Ops UI: super-admin console → **Code Run** (`/ops/admin/agent-code-run`).
One-time env → DB migration (dev/staging):
```bash
node scripts/migrate-agent-code-run-config-from-env.mjs --dry-run
node scripts/migrate-agent-code-run-config-from-env.mjs --updated-by <admin-user-uuid>
```
Verify effective policy after save:
```bash
curl -fsS http://127.0.0.1:8081/auth/status -H "Cookie: h5_user=<token>" | jq '.agentCodeRun'
curl -fsS http://127.0.0.1:8081/api/runtime/status | jq '.toolRuntime.codeRunPolicy'
```
Page Data dev loop (local only):
```bash
MEMIND_TOOL_GATEWAY_ENABLED=1 npm run dev:page-data-aider-loop -- --dry-run
```
See also: [help-code01.md](./help-code01.md), [help-code02.md](./help-code02.md).
## One-user Canary Profile
Use only for a controlled john-user canary.
+373
View File
@@ -0,0 +1,373 @@
# Help Code01Aider 补充 Page Data 简单系统开发方案
> 文档版本:2026-07-23
> 状态:方案设计(未实施)
> 目标:用 **Aider** 在 Goose 主路径之外,补充 Page Data 简单系统在**开发/调试**阶段的修 bug 与测试回归;**不替代 Goose**,不替代 `page-data-collect` skill。
---
## 1. 背景与目标
### 1.1 现状
Memind 的 Page Data 主路径由 **Goose + `page-data-collect` skill + sandbox-fs MCP** 完成:
```text
load_skill(page-data-collect)
→ private_data_execute(建表)
→ private_data_register_dataset(注册 dataset
→ write_filesurvey.html + admin.html
→ private_data_bind_workspace_page(发布 + 策略)
```
**Aider / OpenHands** 当前仅在 `toolMode='code'` 的显式代码任务中作为外部执行器,**不参与** Page Data 创建与日常 H5 聊天。
### 1.2 痛点
简单 Page Data 系统(问卷、台账、小后台)在 Goose 搭完骨架后,开发阶段常见:
- HTML 字段名与 dataset 列不一致 → insert 403
- `page-data-client.js` 用法错误
- policy 白名单未更新(bind 失败或漏列)
- admin 页读不到数据
- 改完不确定是否回归通过
重新走聊天让 Goose 修,成本高、周期长。
### 1.3 目标
引入 **Aider 作为 L2 开发兜底**
| 阶段 | 执行者 |
|------|--------|
| **创建** | Goose + `page-data-collect`(不变) |
| **测试** | 现有 verify / scenario 脚本(不变) |
| **修 bug** | Aider(新增,仅 dev/staging |
| **改表 / 重新 bind** | Goose 或运维脚本(Aider 不主责) |
---
## 2. 设计原则
1. **不替代 Goose**:Page Data 首次建表、注册、bind 仍走 MCP 主路径。
2. **测试驱动**Aider 修复必须以 verify 脚本失败输出为依据,禁止无验收的盲改。
3. **cwd 隔离**:用户 workspace 与 Memind 平台源码分开,不可混跑。
4. **dev 优先**:生产环境默认不自动触发 Aider Page Data 修复;需白名单与 code run 灰度。
5. **简单系统用 Aider**:复杂多文件改造才考虑 OpenHands,本方案默认 `executor=aider`
---
## 3. 三层架构
```mermaid
flowchart LR
A[Goose page-data-collect] --> B[产物: HTML + PG表 + policy]
B --> C[npm verify / 场景脚本]
C -->|失败| D[Aider code run]
D --> E[改 workspace 内文件]
E --> C
C -->|通过| F[交付]
```
### 3.1 L0 — 创建(Goose,不变)
- Skill`skills/page-data-collect/SKILL.md`
- MCP`mindspace-sandbox-mcp.mjs``private_data_*` + `write_file` / `edit_file`
- 守卫:`mindspace-page-data-finish-guard.mjs`、交付 sync
### 3.2 L1 — 测试(平台脚本,不变)
| 命令 | 用途 |
|------|------|
| `npm run verify:page-data` | Page Data 平台单测与集成测 |
| `npm run verify:children-hobby-diet-survey` | 问卷链路产物验证(~5s |
| `npm run test:scenario:john4-diet` | 全链路 E2E(含 Agent 聊天,~310min |
| `npm run verify:page-data-delivery` | 绑定/delivery dry-run |
| `npm run repair:page-data-bindings` | 修复 workspace bind |
参考:`.claude/skills/memind-page-data-survey-verify/SKILL.md`
### 3.3 L2 — 修 bugAider,本方案新增)
- 入口:`toolMode='code'``executor='aider'`,建议 `taskType='page_data_dev'`
- cwd:用户 workspace`resolveWorkingDir(userId)`)或 Memind 仓库(平台开发)
- 输入:verify 失败输出 + 目标文件路径 + Page Data 约束摘要
- 输出:修改后的 HTML / policy JSON;可选 receipt
- 验收:重跑 L1 verify 直至通过
---
## 4. Aider 能力边界
### 4.1 ✅ 适合修复
| 问题类型 | 可改路径 |
|----------|----------|
| HTML 字段与 dataset 列不一致 | `public/*-survey.html``public/*-admin.html` |
| `page-data-client.js` API 误用 | 同上 |
| policy insert/read 白名单错误 | `.mindspace/page-data-policies/{pageId}.json` |
| CSP / 脚本路径 / 同源约束 | `public/assets/``public/*.html` |
| 提交后 UI 无反馈 | HTML 内 JS |
### 4.2 ⚠️ 需配合脚本或 Goose
| 问题 | 推荐做法 |
|------|----------|
| PG 表缺列 | Goose 重新 `private_data_execute`,或运维 SQL |
| dataset 未注册 | `scripts/ensure-page-data-datasets.mjs` |
| bind 丢失 | `npm run repair:page-data-bindings` |
| 策略索引不同步 | `page-data-policy-index` 相关 repair |
### 4.3 ❌ 不交给 Aider
| 问题 | 原因 |
|------|------|
| 首次建表 + register + bind | 无 `private_data_*` MCP |
| 替代 Goose 做页面生成 | 缺 skill、finish sync、交付守卫 |
| 生产环境无人值守自动改码 | 风险高,需严格灰度 |
---
## 5. 两种开发场景
### 5.1 场景 A:用户 workspace 里的 Page Data 小系统
**典型产物:**
```text
MindSpace/{userId}/
public/my-survey.html
public/my-admin.html
.mindspace/page-data-policies/{pageId}.json
```
**Aider 配置:**
| 项 | 值 |
|----|-----|
| cwd | `MindSpace/{userId}/` |
| executor | `aider` |
| taskType | `page_data_dev`(建议新增)或 `page_edit_code_task` |
| validation | `expectedFiles`: 目标 `public/*.html` |
**测试裁判:** 问卷专用 verify 或自定义 `scripts/verify-*.mjs`
### 5.2 场景 BMemind 平台 Page Data 模块开发
**典型修改:**
- `page-data-service.mjs``page-data-public-service.mjs`
- `mindspace-page-data-finish-guard.mjs`
- `public/assets/page-data-client.js`
**Aider 配置:**
| 项 | 值 |
|----|-----|
| cwd | `/Users/john/Project/Memind`(或 CI checkout 路径) |
| executor | `aider` |
| taskType | `h5_chat_code_task` 或专用 `page_data_platform_dev` |
| validation | receipt + 单测通过 |
**测试裁判:** `npm run verify:page-data`
> **禁止**在同一次 Aider run 中混用场景 A 与 B 的 cwd。
---
## 6. 开发闭环操作手册
### 6.1 前置:开启 code run
> **Phase 1(当前):** env + VITE,适合本机 dev。
> **Phase 1.5(目标):** memindadm 配置 + `/auth/status` 下发,见 [help-code02.md](./help-code02.md)。
```bash
# .env 示例(开发机,Phase 1
MEMIND_AGENT_CODE_RUNS_ENABLED=1
MEMIND_TOOL_GATEWAY_ENABLED=1
MEMIND_TOOL_GATEWAY_DEFAULT_EXECUTOR=aider
VITE_AGENT_CODE_RUNS_ENABLED=1
VITE_AGENT_PAGE_DATA_DEV_AUTODETECT=1
VITE_AGENT_CODE_RUNS_USER_IDS=<dev-user-uuid> # 或留空表示全用户(仅 dev
# 可选:MEMIND_AGENT_CODE_RUN_TASK_TYPES=page_data_dev,h5_chat_code_task,...
```
还需:
- DB `h5_capability_grants`:目标用户 `aider=true`
- `h5_llm_executor_bindings`aider 有 enabled 的 provider/model
- Portal 或 external worker 之一启用 Tool Gateway(本地 dev 可 Portal 直开)
### 6.2 标准循环
```bash
# 1. 确认 Portal
curl -sf http://127.0.0.1:8081/auth/status
# 2. Goose 已建好 Page Data 系统(聊天或 scenario
# 3. 跑验证
npm run verify:children-hobby-diet-survey
# 或
npm run verify:page-data
# 4. 若失败 → 触发 AiderH5 / agent-run / 独立脚本)
# instruction 必须包含完整 verify 失败输出
# 5. Aider 改完 → 回到步骤 3,直至全绿
```
### 6.3 H5 触发话术示例
- 「问卷 submit 403,列 q4_diet_meals 不允许,请根据 verify 结果修 HTML 和 policy」
- 「Page Data admin 页读不到数据,测试脚本报 policy read 未开启」
- 「修 page-data 简单系统的 bug,不要改表,只改 public HTML」
### 6.4 Aider instruction 模板
```text
[Page Data 开发修复任务]
工作目录: MindSpace/{userId}/
taskType: page_data_dev
验证失败输出(必须原样附上):
<paste verify script stderr/stdout>
目标文件(仅可改这些):
- public/{survey}.html
- public/{admin}.html
- .mindspace/page-data-policies/{pageId}.json
约束:
- 必须使用 /assets/page-data-client.js 公开 API
- 禁止 localStorage / sessionStorage / IndexedDB
- 禁止自建 Express 或独立后端
- 列名必须与 dataset register 的 insert/read 白名单一致
- 不要修改 Memind 平台源码
验收:
- 修改后应能通过: npm run verify:children-hobby-diet-survey
- 或: node scripts/verify-<your-scenario>.mjs
```
---
## 7. 与现有 Memind 架构的集成点
### 7.1 现有组件(复用,不重写)
| 组件 | 路径 | 角色 |
|------|------|------|
| Agent Run 队列 | `agent-run-gateway.mjs` | code run 调度 |
| Tool Gateway | `tool-gateway.mjs` | spawn Aider |
| Launch Plan | `llm-providers.mjs` | `aider --message ... --yes-always` |
| 前端 code 检测 | `src/utils/agentRunMode.ts` | `toolMode:'code'` |
| 能力门禁 | `capabilities.mjs` | code mode 才注入 aider |
| Page Data 路由 | `page-data-routes.mjs` | 运行时 APIAider 不直接调,HTML 调) |
### 7.2 建议新增(实施阶段)
| 项 | 说明 | 优先级 |
|----|------|--------|
| `taskType: page_data_dev` | router / autodetect 识别「修 page data bug」 | P1 |
| chat-intent-router 规则 | 「修问卷/测试没过/page data bug」→ code run | P1 |
| `buildAgentRunTaskValidation` 扩展 | page_data_dev 的 expectedFiles + receipt | P2 |
| 独立 dev 脚本 | 仓库外或 `scripts/page-data-aider-dev-loop.mjs`verify → aider → verify | P2 |
| 文档索引 | 在 `docs/regression-guards/` 或 AGENTS.md 加链接 | P3 |
### 7.3 不建议的做法
- 用 Aider/OpenHands **替代** Goose 做 Page Data 创建
-`page-data-collect` skill 充当通用 code executor
- 生产默认全开 `MEMIND_AGENT_CODE_RUNS_ENABLED` 给所有用户
- 无 verify 输出让 Aider 盲改 workspace
---
## 8. 与 OpenHands / Cursor 的关系
| 引擎 | 本方案中的角色 |
|------|----------------|
| **Goose** | L0 创建(主路径,不变) |
| **Aider** | L2 简单 Page Data dev 修 bug**本方案核心** |
| **OpenHands** | 可选 L3:Aider 失败且涉及多文件/复杂 repo 时再 escalation |
| **Cursor SDK** | 非必需;仅 Memind 平台源码开发或 IDE 级工具时可选用 |
OpenHands 任务类型保持现有 `repo_refactor,multi_file,complex_repo`**不必**为 Page Data 简单 HTML bug 默认走 OpenHands。
---
## 9. 风险与运维
| 风险 | 缓解 |
|------|------|
| Aider 误改非目标文件 | validation `expectedFiles` + cwd 沙箱 + prompt 白名单 |
| 表结构问题被误当 HTML bug | verify 区分 `columns_not_allowed` vs `table_not_found`;后者回 Goose |
| code run 孤儿化导致 H5 loading | verify 脚本检查 orphan running`--no-runs` 可选 |
| 生产误触发 | 生产 `MEMIND_AGENT_CODE_RUNS_ENABLED=0` 或严格 user allowlist |
| PG 连接失败 | fail closedskill 已有);Aider 不得「先写 HTML 等 PG 恢复」 |
---
## 10. 实施路线图
### Phase 0 — 文档与手动流程(当前)
- [x] 本方案文档 `docs/help-code01.md`
- [ ] 开发者在本地手动:verify 失败 → 复制输出 → H5/code run 触发 Aider → 再 verify
### Phase 1 — 最小 Memind 改动
- [x] 新增 `page_data_dev` taskType
- [x] `chat-intent-router` 增加 Page Data 修 bug 意图
- [x] `agentRunMode.ts` 可选 autodetect 模式(dev only`VITE_AGENT_PAGE_DATA_DEV_AUTODETECT`
### Phase 1.5 — memindadm 运行时策略(推荐下一步)
> 详细设计见 **[help-code02.md](./help-code02.md)**。
- [x] `h5_agent_code_run_config` 表 + `agent-code-run-admin-config.mjs`
- [x] memindadm API`/admin-api/agent-code-run/config``/runtime`UI 表单待做)
- [x] `/auth/status` 下发 `agentCodeRun`H5 不再依赖 `VITE_*` rebuild
- [x] `agent-run-routes.mjs` 从 DB 读策略(env 仅紧急 override
- [x] Worker 拓扑(`MEMIND_TOOL_GATEWAY_ENABLED`)继续留 env
- [x] `scripts/migrate-agent-code-run-config-from-env.mjs`
**为何需要 Phase 1.5** Phase 1 的 env/VITE 适合 dev;要解决「用户经常失败」的运营灰度,必须在 memindadm 按用户/任务类型动态开关,且 H5 需运行时生效。
### Phase 2 — 自动化 dev loop
- [x] `scripts/page-data-aider-dev-loop.mjs`:读 verify 输出 → 调 Tool Gateway/Aider → 重跑 verify
- [x] `npm run dev:page-data-aider-loop` 快捷入口
- [ ] 接入 CI optional job(仅 staging
- [x] `npm run ci:page-data-dev-loop-smoke`dry-run 烟测,可挂 CI optional job
### Phase 3 — 可选 escalation
- [x] Aider 连续 N 次 verify 失败 → 升级 OpenHands`taskType=page_data_dev_complex``--escalate-after`
- [x] 运维面板展示 page_data_dev run 历史(`/admin-api/agent-code-run/runs` + Ops UI
---
## 11. 相关文档与命令速查
| 资源 | 路径 / 命令 |
|------|-------------|
| **adm 运行时策略(Phase 1.5** | `docs/help-code02.md` |
| Page Data API 用法 | `docs/page-data-api-usage.md` |
| page-data-collect skill | `skills/page-data-collect/SKILL.md` |
| 问卷 verify skill | `.claude/skills/memind-page-data-survey-verify/SKILL.md` |
| Tool Gateway 架构 | `docs/architecture/memind-2-streaming-agent-runtime-plan.md` |
| Agent run worker | `docs/agent-run-worker-rollout-runbook.md` |
| `npm run verify:page-data` | Page Data 平台测试 |
| `npm run verify:children-hobby-diet-survey` | 问卷产物验证 |
| `npm run repair:page-data-bindings` | 修复 bind |
---
## 12. 一句话总结
**Goose 负责把 Page Data 简单系统「建起来」;现有 verify 脚本负责「验对不对」;Aider 负责开发阶段「根据测试结果改 HTML/policy 修 bug」——三者串联,不替代 Goose 主路径。**
+382
View File
@@ -0,0 +1,382 @@
# Help Code02Code Run / Page Data Dev 的 memindadm 运行时策略
> 文档版本:2026-07-23
> 状态:方案设计(未实施)
> 前置:[help-code01.md](./help-code01.md)Aider 补充 Page Data 开发兜底)
> 关联:[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_。**