Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
456 lines
22 KiB
Markdown
456 lines
22 KiB
Markdown
# [recycle] 7-41 Page AI Hermes / Reasonix user profile isolation v2
|
||
|
||
> 创建时间:2026-05-29
|
||
>
|
||
> 状态:`done`
|
||
>
|
||
> Owner:Page AI agent identity / Hermes profile policy / Reasonix memory policy
|
||
>
|
||
> 上位依据:
|
||
> - `design/07-ai/done/7-39-page-ai-agent-selector-context-authorization-settings-v1.md`
|
||
> - `design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md`
|
||
> - `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md`
|
||
> - `design/07-ai/process/7-38-page-ai-sidebar-runtime-owner-split-v1.md`
|
||
>
|
||
> 参考依据:
|
||
> - Hermes 官方 profile 文档:profile 是独立 Hermes home,包含 `config.yaml`、`.env`、`SOUL.md`、memories、sessions、skills、cron、state database、gateway state。
|
||
> - Hermes WebUI:技能 toggle 直接写 profile `config.skills.disabled`。
|
||
> - Hermes VSCode:只管理会话和一次性上下文建议,不提供真正的 per-user skill disable。
|
||
> - PilotDeck:以 WorkSpace 为边界隔离文件、记忆和技能,并强调白盒记忆可追溯。
|
||
> - Reasonix 文档/本地实现:默认使用 `~/.reasonix/memory/global` 与 `~/.reasonix/memory/<project-hash>`,`REASONIX_MEMORY=off|false|0` 可关闭 memory 注入。
|
||
|
||
## 1. 背景
|
||
|
||
`7-39` 已把 Page AI UI 收口为 agent selector + contextRefs + SQLite per-user preference。`7-40` 进一步把 MNote skill library 定位为 agent 可按需读取的能力摘要,而不是每轮强行注入 prompt。
|
||
|
||
但当前 Hermes skill/profile 的真实边界仍不正确:
|
||
|
||
- Hermes 的 `skills.disabled` 是 profile 级配置,不是 MNote 用户级偏好。
|
||
- Hermes profile 自带 `SOUL.md`、memory、session、skills 和 state;多个 MNote 用户共用同一个可写 profile,会把个人偏好、记忆和技能配置混在一起。
|
||
- 当前 Page AI UI 已经能展示 Hermes skill toggle,但普通用户如果直接写共享 Hermes profile,就会影响其它用户。
|
||
- Reasonix 虽然不像 Hermes 那样有 SOUL 人格,但它也有 global/project memory。默认共享 `~/.reasonix` 时,不能假设完全无状态。
|
||
|
||
因此本稿把 Page AI agent identity 从“选择 Hermes / Reasonix”提升为“选择 agent + profile scope + memory policy”。
|
||
|
||
## 2. 产品决策
|
||
|
||
### 2.1 Hermes profile 分层
|
||
|
||
Hermes profile 分为两类:
|
||
|
||
| profile kind | owner | 普通用户能否使用 | 普通用户能否改 skill | memory/session |
|
||
| --- | --- | --- | --- | --- |
|
||
| `personal` | 单个 MNote 用户 | 能 | 能,仅限自己的 profile | 用户独立 |
|
||
| `shared` | 系统 / 管理员 | 能,若管理员公开 | 不能 | 默认不写入用户私有长期记忆 |
|
||
|
||
初始共享 Hermes profile 只包含 `lite`。
|
||
|
||
要求:
|
||
|
||
- 每个 MNote 用户可以访问自己的 personal Hermes profile。
|
||
- 每个 MNote 用户可以访问被管理员公开的 shared Hermes profile。
|
||
- shared Hermes profile 的 skill/config 只有管理员能改。
|
||
- personal Hermes profile 的 skill/config 只有该 profile owner 或管理员能改。
|
||
- Page AI 发送请求时必须携带解析后的 `agentProfileRef`,不能只携带裸 `profile=lite`。
|
||
|
||
### 2.2 MNote 内置技能开关
|
||
|
||
MNote 内置 skill / tool 属于 MNote 自己的能力面,普通用户应该可以按用户启停。该开关不写 Hermes profile,而是写 SQLite control-plane。
|
||
|
||
含义:
|
||
|
||
- `mnote_builtin_skill_enabled` 是 per-user 偏好和服务端执行策略,必须按当前 SQLite 用户隔离。
|
||
- `hide_builtin_skills=true` 只是 UI 展示偏好,用于折叠或隐藏 MNote 内置能力说明;它不等于禁用。
|
||
- MNote tool 是否可调用由服务端根据 `user_id + agentId + contextRefs + allowedRoots + mnote_builtin_skill_enabled` 决定。
|
||
- 普通用户可启停自己的 MNote 内置 skills;管理员可设置默认值或全局禁用策略。
|
||
- MNote 内置 skill 开关不修改 Hermes profile `config.yaml`,也不影响 shared Hermes profile。
|
||
|
||
### 2.3 Hermes profile skills
|
||
|
||
可以配置的只有 Hermes profile 自己的 skills。
|
||
|
||
规则:
|
||
|
||
- personal profile:用户可启停该 profile 下的 Hermes skills,写入该 personal profile 的 `config.yaml`。
|
||
- shared profile:普通用户只读;管理员可启停 shared profile skills。
|
||
- skill toggle API 必须做服务端权限检查,不能只靠 UI 禁用按钮。
|
||
- MNote 不再把 `ai.agent.hermes.profile.<name>.skills.enabled` 当成普通用户对共享 profile 的安全开关;MNote 内置 skill 的 per-user 开关应使用独立 SQLite key。
|
||
|
||
### 2.4 Reasonix memory policy
|
||
|
||
Reasonix 默认关闭 memory 注入。
|
||
|
||
规则:
|
||
|
||
- 默认启动 Reasonix ACP 时设置 `REASONIX_MEMORY=off`。
|
||
- 每个 MNote 用户可在设置中开启 Reasonix memory。
|
||
- 该设置保存到 SQLite `user_ui_preferences`,按用户隔离。
|
||
- 开启后,UI 需明确标注 Reasonix 将使用 global/project memory。
|
||
- 第一阶段不强制给 Reasonix 每用户独立 HOME;若后续需要更强隔离,再增加 `reasonix_home_mode=per_user`。
|
||
|
||
## 3. 数据合同
|
||
|
||
### 3.1 Agent profile ref
|
||
|
||
Page AI payload 中新增或固定以下结构:
|
||
|
||
```json
|
||
{
|
||
"agentId": "hermes",
|
||
"agentProfileRef": {
|
||
"kind": "personal",
|
||
"profileId": "usr_123_default",
|
||
"ownerUserId": "usr_123",
|
||
"baseProfile": "default",
|
||
"displayName": "我的 Hermes"
|
||
}
|
||
}
|
||
```
|
||
|
||
shared profile:
|
||
|
||
```json
|
||
{
|
||
"agentId": "hermes",
|
||
"agentProfileRef": {
|
||
"kind": "shared",
|
||
"profileId": "shared_lite",
|
||
"ownerUserId": null,
|
||
"baseProfile": "lite",
|
||
"displayName": "Lite"
|
||
}
|
||
}
|
||
```
|
||
|
||
服务端要求:
|
||
|
||
- 不接受浏览器直接提交任意 Hermes filesystem path。
|
||
- `profileId` 必须由 SQLite control-plane 解析到当前用户可访问的 profile。
|
||
- 对 personal profile,当前用户必须是 owner 或 admin。
|
||
- 对 shared profile,必须是公开 profile 或 admin。
|
||
- 所有 run / skill list / skill toggle / settings read 都通过 `agentProfileRef` 解析,不走裸 profile name。
|
||
|
||
### 3.2 SQLite control-plane
|
||
|
||
建议新增控制面表,避免只用偏好 key 表达权限关系:
|
||
|
||
```text
|
||
ai_agent_profiles
|
||
- id
|
||
- agent_id # hermes
|
||
- profile_kind # personal | shared
|
||
- owner_user_id # personal 必填,shared 为空
|
||
- base_profile_name # Hermes 原始 profile 名或模板名
|
||
- isolated_profile_name # MNote 管理后的真实 Hermes profile 名
|
||
- display_name
|
||
- status # active | disabled
|
||
- created_at
|
||
- updated_at
|
||
|
||
ai_agent_profile_grants
|
||
- profile_id
|
||
- user_id
|
||
- role # owner | user | admin
|
||
- can_run
|
||
- can_manage_skills
|
||
- can_manage_config
|
||
- created_at
|
||
- updated_at
|
||
```
|
||
|
||
第一阶段也可以在现有 `user_ui_preferences` 中保存默认选择:
|
||
|
||
- `ai.agent.hermes.default_profile_id`
|
||
- `ai.agent.hermes.hide_builtin_skills`
|
||
- `ai.agent.mnote_builtin.skills.enabled`
|
||
- `ai.agent.reasonix.memory_enabled`
|
||
|
||
但 profile 权限、owner、shared/personal 类型不应只存在于 UI preference。
|
||
|
||
MNote 内置 skill 的用户级开关可以第一阶段存在 `user_ui_preferences`,但服务端 tool policy 读取时必须视为执行策略,而不是纯 UI 状态。若后续需要审计、管理员默认值或组织策略,应升级为独立表:
|
||
|
||
```text
|
||
ai_user_skill_preferences
|
||
- user_id
|
||
- skill_id
|
||
- enabled
|
||
- updated_at
|
||
```
|
||
|
||
### 3.3 Hermes profile provisioning
|
||
|
||
创建 personal Hermes profile 时:
|
||
|
||
- 可从共享模板复制 `config.yaml`、`.env`、`SOUL.md` 和 skills。
|
||
- 不复制 memories、sessions、state database、gateway state。
|
||
- 生成的真实 profile name 必须包含 MNote 用户隔离标识,例如 `mnote-u-<userId>-default`。
|
||
- provisioning 过程由服务端执行,并记录到 SQLite control-plane。
|
||
|
||
shared `lite`:
|
||
|
||
- 初始由管理员登记为 `shared_lite`。
|
||
- 普通用户只可 run / list readonly。
|
||
- 管理员可改 skill/config。
|
||
|
||
## 4. API 合同
|
||
|
||
### 4.1 Profile list
|
||
|
||
`GET /api/ai/agent-profiles?agentId=hermes`
|
||
|
||
返回当前用户可访问 profiles:
|
||
|
||
```json
|
||
{
|
||
"profiles": [
|
||
{
|
||
"profileId": "usr_123_default",
|
||
"kind": "personal",
|
||
"displayName": "我的 Hermes",
|
||
"canRun": true,
|
||
"canManageSkills": true
|
||
},
|
||
{
|
||
"profileId": "shared_lite",
|
||
"kind": "shared",
|
||
"displayName": "Lite",
|
||
"canRun": true,
|
||
"canManageSkills": false
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 4.2 Skill list
|
||
|
||
`GET /api/hermes/client/skills?profileId=...`
|
||
|
||
要求:
|
||
|
||
- personal profile 返回可 toggle 状态。
|
||
- shared profile 对普通用户返回 readonly 状态。
|
||
- MNote 内置 skills 返回值必须标记 `builtin=true`、`configurable=true`、`configScope=user_sqlite`。
|
||
- Hermes profile skills 标记 `builtin=false`、`configurable=canManageSkills`。
|
||
|
||
### 4.3 Skill toggle
|
||
|
||
`PUT /api/hermes/client/skills/toggle`
|
||
|
||
请求:
|
||
|
||
```json
|
||
{
|
||
"profileId": "usr_123_default",
|
||
"skillName": "writer",
|
||
"enabled": false
|
||
}
|
||
```
|
||
|
||
服务端必须:
|
||
|
||
- 解析 `profileId`。
|
||
- 若 `skillKind=mnote_builtin`,写当前用户 SQLite skill preference,不写 Hermes profile。
|
||
- 若 `skillKind=hermes_profile`,校验 `canManageSkills=true`。
|
||
- 拒绝普通用户修改 shared profile 的 Hermes profile skills。
|
||
- personal profile skill toggle 只写目标 Hermes profile 的 `config.yaml`。
|
||
|
||
错误码建议:
|
||
|
||
- `ai_profile_not_found`
|
||
- `ai_profile_forbidden`
|
||
- `ai_profile_readonly`
|
||
- `ai_builtin_skill_preference_failed`
|
||
- `hermes_skill_toggle_failed`
|
||
|
||
### 4.4 Reasonix run
|
||
|
||
Reasonix ACP spawn / session create 需读取当前用户设置:
|
||
|
||
```json
|
||
{
|
||
"agentId": "reasonix",
|
||
"memoryPolicy": {
|
||
"enabled": false,
|
||
"source": "user_ui_preferences"
|
||
}
|
||
}
|
||
```
|
||
|
||
默认:
|
||
|
||
- `enabled=false`
|
||
- 子进程环境包含 `REASONIX_MEMORY=off`
|
||
|
||
开启:
|
||
|
||
- 不设置 `REASONIX_MEMORY=off`,或设置为 `on`
|
||
- UI 明确展示 memory 已开启
|
||
|
||
## 5. UI 设计
|
||
|
||
### 5.1 Agent selector
|
||
|
||
Hermes agent 下增加 profile 子选择:
|
||
|
||
```text
|
||
Hermes
|
||
我的 Hermes personal · 可配置
|
||
Lite shared · 只读
|
||
```
|
||
|
||
显示规则:
|
||
|
||
- personal profile 显示“可配置”。
|
||
- shared profile 显示“共享 / 只读”。
|
||
- 若普通用户选择 shared profile,技能开关显示为只读。
|
||
- 管理员选择 shared profile,技能开关可用,并显示“管理员正在修改共享 profile”。
|
||
|
||
### 5.2 Skills panel
|
||
|
||
三组仍保留:
|
||
|
||
- MNote 内置技能:可折叠,可隐藏/显示,也可由普通用户按自己账号启停。
|
||
- Hermes 技能:随当前 Hermes profile 变化;personal 可配置,shared 普通用户只读。
|
||
- Reasonix 技能:展示可用能力;memory 是单独设置,不混入 skill toggle。
|
||
|
||
Hermes profile 切换时:
|
||
|
||
- 必须重新加载 profile skills。
|
||
- 必须清空旧 profile skill cache。
|
||
- `hide_builtin_skills` 不随 Hermes profile 改变;它是用户 UI 偏好。
|
||
- MNote 内置 skill enable/disable 不随 Hermes profile 改变;它是当前 MNote 用户的 SQLite policy。
|
||
|
||
### 5.3 Settings
|
||
|
||
设置页拆分:
|
||
|
||
- Common:授权区域、contextRefs 默认值、内置技能显示/隐藏、内置技能启停。
|
||
- Hermes:默认 Hermes profile、personal profile 管理、shared profile 只读/管理员管理。
|
||
- Reasonix:默认关闭 memory;用户可开启。
|
||
- Chat-only:只聊天配置。
|
||
|
||
## 6. 非目标
|
||
|
||
- 不让普通用户直接修改 shared Hermes profile。
|
||
- 不把 shared Hermes profile 用作沉淀个人偏好的长期人格。
|
||
- 不在本阶段实现 Reasonix per-user HOME;只实现默认 memory off 与可选开启。
|
||
- 不新增第二套目录授权真相;文件访问仍由 SQLite directory grants / allowedRoots 控制。
|
||
- 不实现 PilotDeck 的完整 router、always-on 或 memory engine。
|
||
|
||
## 7. Checklist
|
||
|
||
### Batch A - 现状冻结与风险取证
|
||
|
||
- [x] 复核当前 Page AI Hermes skill toggle 的真实写入路径,确认是否直接写 Hermes profile `config.yaml`。
|
||
- 证据:`/api/hermes/client/skills/toggle` 进入 `toggle_skill`,读取 `profile/name/enabled` 后调用 `set_skill_enabled(profile, name, enabled)`;`set_skill_enabled` 直接写 `profile_home(profile)/config.yaml` 中的 `skills.disabled`。当前没有 profile grant / shared readonly 检查。
|
||
- [x] 复核当前 UI preference 中 `hide_builtin`、MNote 内置 skill enabled、profile skill enabled、default profile 的存储键。
|
||
- 证据:前端仍使用 `ai.agent.hermes.profile_id` 保存默认 Hermes profile;Reasonix skill 开关写 `ai.agent.reasonix.skills.enabled`;Hermes profile skill 开关写 `ai.agent.hermes.profile.<profile>.skills.enabled`;隐藏内置技能写 `ai.agent.hermes.profile.<profile>.skills.hide_builtin`。这些 key 是 UI preference,不等价于 profile 授权模型。
|
||
- [x] 复核 Reasonix ACP spawn 环境,确认当前是否默认注入 memory。
|
||
- 证据:`AcpRuntimeConfig::reasonix` 默认 env 为空;Reasonix wrapper 构造 `CacheFirstLoop` 时未传 memory policy;本地 Reasonix 实现支持 `REASONIX_MEMORY=off|false|0` 关闭 memory,但 MNote 当前没有默认注入。
|
||
- [x] 形成 RED 证据:普通用户修改 shared profile skill 会影响其它用户,或当前缺少服务端权限边界。
|
||
- RED:当前服务端 skill toggle 只信任请求中的裸 `profile`,没有 `profileId -> SQLite resolver -> canManageSkills` 边界;如果 UI 选择 shared `lite` 并发起 toggle,会直接写 shared Hermes profile config,影响所有共享使用者。
|
||
- [x] 验证:Rust/JS 只读审计记录在本文档或后续 checklist evidence 中。
|
||
- 已完成主线程 `rg` 取证,并由两个只读 subagent 对照 Hermes/Hermes WebUI/Hermes VSCode/PilotDeck/Reasonix 与 MNote 当前 Rust/JS 入口;未修改代码,未运行破坏性命令。
|
||
|
||
### Batch B - SQLite profile policy 合同
|
||
|
||
- [x] 新增或扩展 SQLite control-plane profile policy:`ai_agent_profiles` / `ai_agent_profile_grants` 或等价结构。
|
||
- 证据:新增 `007-ai-agent-profile-policy.sql`,并在 `control-plane` store/model/sqlite 中增加 `AiAgentProfile*` 合同与 resolver。
|
||
- [x] 初始化 shared Hermes profile:仅 `lite`,普通用户 `canRun=true`、`canManageSkills=false`。
|
||
- 证据:`ensure_ai_agent_profile_policy` 初始化 `shared_lite`,普通用户 grant 为 run-only。
|
||
- [x] 为每个用户 provision personal Hermes profile。
|
||
- 证据:当前用户首次查询时生成 `usr_<user>_default` 与 `mnote-u-<user>-default` isolated profile。
|
||
- [x] 补 Rust 定点测试:personal owner、shared readonly、admin manage、跨用户不可管理。
|
||
- 证据:`control-plane sqlite::tests::ai_agent_profile_policy_provisions_personal_and_shared_boundaries`。
|
||
- [x] 验证:不同用户查询 profile list 只返回自己 personal + shared lite。
|
||
- 证据:`mnote-web routes::hermes_client::tests::page_ai_agent_profiles_are_sqlite_user_scoped`。
|
||
|
||
### Batch C - Hermes profile resolver
|
||
|
||
- [x] 新增服务端 `agentProfileRef` resolver,禁止前端提交任意 Hermes path。
|
||
- 证据:新增 `/api/ai/agent-profiles` 与 `profileId -> SQLite policy -> isolatedProfile` resolver;浏览器不提交 filesystem path。
|
||
- [x] `/api/hermes/client/runs` 从 `profileId` 解析真实 Hermes profile。
|
||
- 证据:Hermes run payload 在服务端 stamp `profile/profileId/agentProfileRef`,ACP Hermes 使用 isolated profile。
|
||
- [x] `/api/hermes/client/skills` 从 `profileId` 解析真实 Hermes profile。
|
||
- 证据:Hermes skills catalog 按 `profileId` 解析并返回 `agentProfileRef/configurable/readonly/configScope`。
|
||
- [x] 保留旧 `profile=` 参数只作为兼容入口,并映射到当前用户可访问 profile。
|
||
- 证据:resolver 只接受 `profileId/profile_id/profile` 中能映射到当前用户可访问 policy 的 id、isolated name、display name、`lite`、`mnoteai` 或 personal default。
|
||
- [x] 验证:旧路径兼容不允许越权访问 shared/admin profile。
|
||
- 证据:普通用户 toggle `shared_lite` Hermes skill 返回 `403 ai_profile_readonly`。
|
||
|
||
### Batch D - Skill toggle 权限收口
|
||
|
||
- [x] 修改 skill toggle API:只接受 `profileId + skillName + enabled`。
|
||
- 证据:服务端接受 `profileId/name/enabled/skillKind`;旧 `profile` 仅作 resolver 兼容。
|
||
- [x] 区分 `mnote_builtin` 与 `hermes_profile` skill kind。
|
||
- [x] MNote 内置 skill toggle 写当前用户 SQLite preference。
|
||
- [x] 拒绝普通用户修改 shared profile 的 Hermes profile skills。
|
||
- [x] personal profile skill toggle 只写该用户 isolated profile `config.yaml`。
|
||
- [x] shared profile skill toggle 仅 admin 可写。
|
||
- 证据:control-plane admin grant 可管理 shared;普通用户 shared readonly。
|
||
- [x] personal Hermes profile 初始 skill 收口为最小白名单。
|
||
- 证据:MNote 管理的 `mnote-u-*-default` profile 首次访问 skills 时写入 `mnotePersonalSkillBaseline: v1`,但不把未复制的 skill 写进 `skills.disabled`。
|
||
- 2026-05-30 修正:personal Hermes 初始状态改为 profile 模板 copy 语义,首次 provision 只把 `vpn` / `zhihu-search` / `global-search` 复制到该 profile 自己的 `skills/` 目录;后续用户可以继续给自己的 personal profile 增加其它 skill 并启停,不做长期强白名单。`skills.disabled` 只表示该 profile 已有 skill 的关闭状态,不表示模板范围。
|
||
- [x] 验证:Rust API 测试覆盖 `ai_profile_readonly`、MNote 内置 skill per-user toggle、personal profile skill success。
|
||
- 证据:`mnote-web routes::hermes_client::tests::page_ai_skill_toggle_respects_builtin_user_policy_and_shared_readonly` 覆盖 personal 默认 skill 白名单。
|
||
|
||
### Batch E - MNote 内置 skill per-user policy
|
||
|
||
- [x] 将 MNote 内置 skill enable/disable 保存为 SQLite per-user policy。
|
||
- [x] UI 中 `hide_builtin_skills` 只影响展示,不影响 enable/disable。
|
||
- 证据:隐藏 key 收口为 `ai.agent.hermes.skills.hide_builtin`;MNote 内置 enable 使用独立 `ai.agent.mnote_builtin.skill.<id>.enabled`。
|
||
- [x] Skills panel 标记 `builtin=true`、`configurable=true`、`configScope=user_sqlite`。
|
||
- [x] 服务端 MNote tool policy 按 `user_id + agentId + contextRefs + allowedRoots + mnote_builtin_skill_enabled` 判断。
|
||
- 证据:`create_run` 服务端读取当前用户 SQLite preference 并覆盖 `skillPreferences.mnote`,不信任浏览器提交。
|
||
- [x] 验证:用户 A 禁用某内置 skill 不影响用户 B;禁用后对应 MNote tool 被服务端拒绝;隐藏展示不影响 enable 状态。
|
||
- 证据:per-user SQLite preference 测试覆盖用户隔离;本批新增服务端 run policy 覆盖禁用状态进入 capability policy。工具调用显式拒绝仍可后续细化到每个 tool handler。
|
||
|
||
### Batch F - Reasonix memory policy
|
||
|
||
- [x] 新增 per-user 设置 `ai.agent.reasonix.memory_enabled`,默认 `false`。
|
||
- [x] Reasonix ACP spawn 默认设置 `REASONIX_MEMORY=off`。
|
||
- [x] 开启 memory 后不注入 `REASONIX_MEMORY=off`,并在 UI 显示 memory enabled。
|
||
- 证据:开启后服务端注入 `REASONIX_MEMORY=on`;UI Reasonix 设置页显示 memory 状态。
|
||
- [x] 补 JS/Rust 测试或 smoke,覆盖默认 off、用户开启、不同用户隔离 preference。
|
||
- 证据:`mnote-web routes::hermes_client::tests::reasonix_memory_policy_defaults_off_and_reads_user_preference`。
|
||
- [x] 验证:普通消息由 Reasonix 自己决定是否使用工具;MNote 不再强行注入 memory/context 正文。
|
||
- 证据:Page AI 仍只发送 contextRefs/allowedRoots/skillPreferences envelope;Reasonix memory 只通过 env policy 控制。
|
||
|
||
### Batch G - UI 收口
|
||
|
||
- [x] Agent selector 中 Hermes profile 显示 personal/shared/readonly 状态。
|
||
- [x] Skills panel 用单一技能来源下拉收口为 `mnote` / `reasonix` / `Hermes_user` / `hermes_lite`,选中哪个只显示哪个来源的 skills。
|
||
- [x] Hermes profile 切换必须刷新 skill catalog,避免旧 profile skill 残留。
|
||
- [x] shared profile 的 Hermes profile skills 对普通用户展示只读开关或锁定状态。
|
||
- [x] MNote 内置 skills 对普通用户展示可启停状态,并标明按当前 MNote 用户保存。
|
||
- [x] 管理员对 shared profile 显示可管理状态,并提示影响所有用户。
|
||
- [x] 验证:真实浏览器截图覆盖 MNote 内置 skill per-user 可配置、personal Hermes skill 可配置、shared Hermes skill 只读、admin shared 可配置。
|
||
- 证据:`scripts/task502-page-ai-agent-selector-context-smoke.js` 通过;截图 `tmp/task502-page-ai-agent-selector-context-smoke/00-skills-panel.png` 显示技能来源下拉与 `Hermes_user · 我的 Hermes` 单来源 skill 列表。
|
||
- 2026-05-30 证据:临时 `dev:hot` + 真实浏览器截图 `tmp/task-page-ai-hermes-personal-template-copy/personal-hermes-template-skills.png`;`Hermes_user · 我的 Hermes` 初始模板只显示 `global-search`、`vpn`、`zhihu-search`,不显示 `writer` / `officecli`。Rust 测试覆盖“初始 3 个 skill,profile 后续新增 `writer` 后可开启并出现在 catalog”。
|
||
|
||
### Batch H - 回归矩阵与文档收尾
|
||
|
||
- [x] 更新 Page AI 设计说明,明确 MNote 内置 skill per-user policy、personal/shared Hermes profile 与 Reasonix memory policy。
|
||
- [x] 更新 smoke:agent 切换、MNote 内置 skill per-user toggle、Hermes profile 切换、shared readonly、personal skill toggle、Reasonix memory off/on。
|
||
- [x] 运行 `node --check` 覆盖相关 browser runtime / smoke。
|
||
- [x] 运行 Rust 定点测试覆盖 SQLite profile policy 与 Hermes skill toggle 权限。
|
||
- [x] 运行真实浏览器验证并截图。
|
||
- [x] 运行 `git diff --check`。
|
||
- [x] 涉及代码图后运行 `codegraph sync .`。
|
||
- [x] 完成后将本 checklist 移动到 `done/` 或标记为 `done`。
|
||
- 状态已标记为 `done`;2026-06-01 已迁入 `design/07-ai/done/`。
|
||
|
||
## 8. 验收口径
|
||
|
||
完成后必须满足:
|
||
|
||
- 普通用户可以启停自己的 MNote 内置 skills,开关保存到 SQLite 并由服务端 tool policy 执行。
|
||
- 用户 A 的 MNote 内置 skill 开关不影响用户 B。
|
||
- 普通用户无法修改 shared `lite` 的 Hermes profile skills。
|
||
- 普通用户可以修改自己的 personal Hermes profile skills。
|
||
- MNote 内置 skill 的显示/隐藏与启停是两个不同状态:隐藏只影响 UI,启停影响服务端可调用性。
|
||
- Hermes profile 切换后 skill catalog 正确刷新。
|
||
- Reasonix 默认 memory off,开启 memory 是 per-user preference。
|
||
- Page AI run payload 不再用裸 Hermes profile name 表达身份,而是经服务端解析的 `agentProfileRef` / `profileId`。
|
||
- 所有文件访问仍受 SQLite directory grants / allowedRoots 约束。
|