Files
mnote/design/07-ai/done/7-71-unified-ai-management-control-plane-and-pi-lab-integration-checklist-v1.md

142 lines
6.7 KiB
Markdown
Raw Permalink 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.
# 7-71 统一 AI 管理面板与 Pi Lab 功能接入 — 实施检查清单
状态:partial — P0/P1/P2 完成;P3/P4/P5 管理员侧 OpenHub-like AI 管理与逐用户配置完成,用户自助偏好与 LightRAG 写管理待后续
日期:2026-07-04
> 本清单与 `design/07-ai/process/7-71-unified-ai-management-control-plane-and-pi-lab-integration-v1.md` 的 §11 进度表保持同步。
> process 文档保留架构结论;本文件记录已完成的检查项供快速验证。
## 已通过验收项
### P0 — 合同与只读聚合 ✅
| 检查项 | 通过 |
|---|---|
| `/api/ai-settings/effective` GET 端点已注册 | ✅ |
| `/api/ai-settings/access-scopes` GET 端点已注册 | ✅ |
| `/api/ai-admin/access-scopes` GET 端点已注册 | ✅ |
| 所有 AI settings/scopes 端点无 POST/PUT/DELETE | ✅ |
| `effective_settings` 使用 `load_active_directory_grants` 生成 allowed roots | ✅ |
| `load_model_policy_and_quota` 不读取 `allowed_roots_json` | ✅ |
| `source_of_truth` 声明为 `"directory_grants"` | ✅ |
| 静态 smoke 27/27 通过 | ✅ |
### P1 — Pi Lab history 入库 ✅
| 检查项 | 通过 |
|---|---|
| `persist_upsert_run` 写入 `ai_runtime_runs` | ✅ |
| `persist_append_event` 写入 `ai_runtime_events` | ✅ |
| `GET /api/page-ai/pi/sessions` 路由注册 | ✅ |
| `GET /api/page-ai/pi/sessions/{id}` 路由注册 | ✅ |
| `GET /api/page-ai/pi/sessions/{id}/events` 路由注册 | ✅ |
| list_sessions 按 pi_lab profile + pi acp_runtime 过滤 | ✅ |
### P2 — Receipt 与 patch 入库 ✅
| 检查项 | 通过 |
|---|---|
| migration v9 新增 `ai_tool_events / ai_file_patches` | ✅ |
| SQLite 与 Turso/libSQL store 均实现 append/list | ✅ |
| Pi tool receipt 默认写 control-plane | ✅ |
| 成功 patch 关联写入 `ai_file_patches` | ✅ |
| JSONL 仅在 control-plane 写失败时作为 debug fallback | ✅ |
| deny reason、diff summary、file version、citation count 可查询 | ✅ |
| receipt 与 patch 按当前用户隔离 | ✅ |
### P3 — AI 管理中心与管理员模型写管理 ✅
| 检查项 | 通过 |
|---|---|
| `/admin/ai` 路由与管理员鉴权 | ✅ |
| `/user/ai` 路由与用户鉴权 | ✅ |
| 账户菜单有独立 AI 管理入口 → `/admin/ai``/user/ai` | ✅ |
| AI 管理页面 SSR 渲染 OpenHub-like 左侧分页与多 section | ✅ |
| Access Scopes 只读展示(无 POST/PUT/DELETE、无写表单) | ✅ |
| Sessions & Receipts 显示真实 Pi session、receipt、patch 数量 | ✅ |
| Providers & Models 管理写操作 | ✅ |
| `/user/ai` 用户可操作设置 | ❌ |
### 独立入口保留检查
| 检查项 | 通过 |
|---|---|
| OpenHub `/page-ai/openhub/ai` | ✅ |
| OpenHub admin guard 路由 | ✅ |
| OpenHub status API | ✅ |
| Pi Lab shell `/page-ai/pi` | ✅ |
| Pi Lab event stream `GET /api/page-ai/pi/events` | ✅ |
| Pi Lab start/send/abort 路由 | ✅ |
### P4 — 工具、Skills/MCP 管理 ✅
| 检查项 | 通过 |
|---|---|---|
| `GET/PUT /api/ai-admin/settings` 原子策略端点 | ✅ |
| 模型 provider、allowed models、角色模型与 failover 写入 | ✅ |
| MNote-owned tools allow/ask/deny 写入 | ✅ |
| Skill 添加、描述、启停、删除 | ✅ |
| MCP transport/command/url/network/secret refs 写入 | ✅ |
| MCP 强制 facade-only 与 sandbox | ✅ |
| 刷新后配置持久存在 | ✅ |
| effective API 投影模型、Skills、MCP | ✅ |
### P5 — 逐用户 AI 配置 ✅
| 检查项 | 通过 |
|---|---|
| OpenHub `UserManagement`、模型/工具/Skill 权限实现已核验 | ✅ |
| `GET /api/ai-admin/users` 用户列表 | ✅ |
| `GET/PUT /api/ai-admin/users/{user_id}/settings` | ✅ |
| 用户可独立选择管理员允许的模型和默认模型 | ✅ |
| 用户工具策略只能相对全局降权 | ✅ |
| 用户 Skill/MCP 只能在全局启用目录中开关 | ✅ |
| 普通用户登录后的 effective API 应用 override | ✅ |
| allowed roots 仍只来自 `directory_grants` | ✅ |
| 用户抽屉采用 OpenHub-like 分组:模型按 provider、工具按 risk、Skill/MCP 开关、目录只读跳统一授权页 | ✅ |
## 后续项
| 项 | 状态 | 说明 |
|---|---|---|
| `/user/ai` 用户可操作偏好 | 未实现 | 当前只读 effective config,不能提升管理员权限 |
| LightRAG source/index/status 写管理 | 未实现 | 继续使用唯一 knowledge provider 与现有 facade |
| provider/skill/MCP 专用规范化表 | 未实现 | 当前原子策略存入 `ai_policies.model_policy_json`;出现独立查询、授权或生命周期需求时迁移 |
## 浏览器证据
- Pi Lab 原生抽屉:`tmp/7-71-pi-lab-browser-final.png`
- AI 管理页:`tmp/7-71-ai-admin-final.png`
- 模型写管理:`tmp/7-71-ai-admin-openhub-like-ui-final/models.png`
- Skills/MCP 写管理:`tmp/7-71-ai-admin-openhub-like-ui-final/skills-mcp.png`
- 逐用户 AI 配置:`tmp/7-71-ai-admin-openhub-like-ui-final/users.png`
- 管理页运行时摘要:会话 1、回执 3、文件补丁 1
- Pi Lab 截图可见真实 mock 回复、citation、diff、abort,且 OpenHub 默认入口仍独立存在
- `mnote-e2e` 通过 control-plane `role=admin` 进入管理员模式;浏览器验收用 dev seed 临时确保测试账号为 admin
- OpenHub 的 MCP 实际为用户工作区 `.opencode/mcp` 文件展示,并非 Admin per-user overrideMNote 采用更严格的管理员注册 + 用户启停 + facade/sandbox 模型
## 验证命令
```bash
# 静态 smoke(只读代码审计,无需启动服务器)
node scripts/task-ai-management-control-plane-static-smoke.js
MNOTE_AI_ADMIN_OUTPUT_DIR=tmp/7-71-ai-admin-openhub-like-ui-final \
node scripts/task-ai-management-browser-smoke.js
node scripts/task-pi-lab-static-smoke.js
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo check -p mnote-web
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane ai_tool_events
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane ai_file_patches
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane migrations
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web ai_settings
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web page_ai_pi
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web ai_admin
# 运行时验证(需要 mnote-web 运行于 localhost:3000
# curl -s http://localhost:3000/api/ai-settings/effective | jq '{source: .sourceOfTruth, models: [.models[].id], rootsCount: (.allowedRoots | length)}'
# curl -s http://localhost:3000/api/ai-settings/access-scopes | jq '.sourceOfTruth'
# curl -s http://localhost:3000/api/ai-admin/access-scopes | jq '.sourceOfTruth'
# curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/admin/ai
# curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/user/ai
```