Files
goodbuddy/docs/features/smart-heartbeat/prd.md
T
mesalogo d80d42b032 feat(storage): move desktop SQLite ownership into a storage utility process
Main no longer opens desktop business SQLite. A single utility-process
storage owner holds the Assistant, Knowledge, attachment, document-result,
remote-binding and native model-ledger databases and runs whole domain
transactions; Main and Runtime callers use explicit async domain operations.

- Remove the Main readWithFallback path and the supervision worker's
  separate business write connection; manifests are scanned read-only and
  committed by the sole writer.
- Remote events are ACKed only after commit; process loss reports
  unconfirmed writes instead of replaying them.
- Use native utilityProcess messaging with one in-flight bound (32) and
  ordered waiting instead of capacity rejection and retries.
- Start the storage process before the window so startup overlaps.
- Keep short tool output in memory and store full output once in owned
  storage; paging, branching, restart and deletion reuse that copy.
- Put required runtime launch files under goodbuddy-prefixed owned temp
  directories and reclaim confirmed stale ones; stop writing duplicate
  parsed.md.
- Add lint guards for SQLite ownership and architecture, concurrency
  acceptance fixtures, and maintenance/architecture documentation.

Validation: typecheck and lint pass. Alternating baseline (edf019aa) vs
candidate runs show no regression on single-session, C01, C02, C04 and a
5-minute C06; Main p99 drops from ~21 ms to ~16.7 ms under concurrency.
Fresh portable copy (1.75M events) upgrade content unchanged; real-model
output paging passes with 4 external requests. Full npm test runs had
1-9 different timing-sensitive failures per run that pass when rerun.
Not covered: C03 review publication, C07 source body, app-level C05.
2026-10-06 15:40:18 +08:00

250 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.
# 智能心跳 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 入口与范围已实现;分区记忆协同待设计 |
| 版本 | 0.6 |
| 日期 | 2026-09-05 |
| 适用产品 | GoodBuddy 桌面端 |
| 文档角色 | 智能心跳当前能力、权威入口、范围和长期边界 |
| 相关设计 | [统一界面设计系统](../../../UI-DESIGN.md) |
| 相关架构 | [自动化、监督与记忆平台总体设计](../../architecture/automation-platform-architecture.md) |
| 相关界面 | [通用助手工作栏与执行空间 PRD](../assistant-workbar/prd.md) |
| Task 模型 | [Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) |
> 本文区分近期实施与长期方向。分区记忆由[分区记忆 PRD](../memory/prd.md)定义;智能心跳
> 不能另行创建平行的记忆类型、表或页面。
## 1. 已确认的产品边界
### 1.1 智能心跳是独立能力
- “监督者 > 自动监督”是计划管理、自动监督报告阅读和建议处理的权威位置,创建与编辑使用 Modal;工作回顾只阅读统一监督结果,运行活动位于活动记录,设置只管理算法参数。内部继续沿用 heartbeat 标识。
- 任务中心和设置中心不复制完整心跳配置表单。
- 智能心跳不并入通用自动化中心,也不作为任务中心条目。
- 现有心跳报告、记忆建议、行动建议和审计历史在本轮继续保留。
心跳与监督者共用应用开关;默认关闭、计划自动运行条件、手动请求及在途运行边界统一见[应用启停与执行](../conversation-supervision/logic-design.md#应用启停与执行)。单条计划的启停与应用启用分别保存,普通任务定时调度不受该应用开关影响。
### 1.2 长期方向:分区记忆协同
已确认的方向只有:
> 智能心跳后续应按分区回顾本地信息,提出对应分区的记忆候选和可选唤起建议。
以下内容尚未设计:
- 新增 Automation、Run 和 Agent 等分区后的逐分区回顾规则。
- 与当前记忆候选、心跳报告和建议的关系。
- 时间与内部事件唤起条件的字段、状态和生命周期。
- 到期后的页面和交互。
- 是否以及如何创建 Task。
- 旧版心跳数据如何迁移。
本轮不得扩展分区记忆类型或表。后续唤起能力必须作为分区记忆条目的可选条件,并继续遵守
该条目的分区读取边界。
## 2. 本轮实施范围
### 2.1 目标
1. 完整自动监督配置统一到“监督者 > 自动监督”,创建与编辑复用同一 Modal 表单。
2. 心跳配置支持 `Global` 或指定一个、多个 Project。
3. 保留现有概览、待处理建议、运行历史和报告能力。
4. 新入口完整可用后,再移除任务中心和设置中心中的重复心跳配置。
5. 旧心跳配置、运行、报告、建议、记忆和任务数据不丢失。
### 2.2 非目标
- 不扩展分区记忆模型或实现唤起条件。
- 不修改 Task、Job 或 Task Center 模型。
- 不新增独立 Automation Center。
- 不移除定时任务现有入口。
- 不扩大智能心跳的工具、目录或网络权限,内部文本分析保持无工具。
- 不让智能心跳跨越配置范围读取数据。
- 不将现有心跳建议静默转换成 Task。
## 3. 智能心跳范围
### 3.1 范围选择
每条心跳配置必须明确选择:
| 范围 | 当前执行语义 |
| --- | --- |
| `Global` | 回顾所有 Project 中允许读取的有界会话和任务,并读取 Global 已确认记忆 |
| 指定 Project | 只回顾选中 Project 的有界会话和任务,并读取 Global 与选中 Project 的已确认记忆 |
指定 Project 可以选择一个或多个项目:
```text
范围
(•) Global
( ) 指定项目
[✓] 网站重构
[ ] 内容运营
[✓] 客户研究
```
- `Global` 与指定 Project 互斥。
- 指定 Project 时至少选择一个项目。
- 多项目使用 Checkbox,不使用 Switch。
- 当前项目只可以作为创建表单的建议默认值,不能在保存时隐式覆盖用户选择。
- 切换当前项目不会改变已经保存的心跳范围。
- Main 必须重新验证所有 Project ID,Renderer 不能扩大范围。
### 3.2 多项目执行
多项目配置的一次心跳仍然是一次运行;有待处理输入时生成一份报告,无变化时只保存运行状态:
- 将选中项目中允许读取的会话、任务和记忆汇总后,再执行现有全局输入上限。
- 不为每个 Project 分别创建 Run、报告、建议或 Task 副本。
- 心跳报告成果以无项目归属保存,并在成果元数据中冻结本次配置范围。
- 心跳产生的项目级记忆建议或行动建议必须明确目标 Project。
- 目标 Project 不明确时,只能生成 Global 记忆建议或不绑定项目的行动建议,不能猜测。
### 3.3 兼容现有配置
旧配置按现有 `projectId` 非破坏映射:
- `projectId` 为空的配置迁移为 `Global`。
- `projectId` 有值的配置迁移为“指定 Project”,且只绑定原项目。
- 迁移不修改启停状态、重复规则、时间、回顾窗口、保留期限、下次运行或历史。
- 项目删除时,只有该项目的配置按现有规则删除;多项目配置移除被删除项目并保留其他范围。
### 3.4 自动增量
定时报告与下游监督分别跳过已成功处理且未修改的来源,均无新输入时不调用模型,活动显示无变化。首次运行受计划范围和回顾窗口限制;预算遗漏、修订和失败重试规则由[监督者逻辑设计](../conversation-supervision/logic-design.md#自动增量与手动重看)统一定义。已确认记忆只提供背景。
“立即运行”保留显式重新生成心跳报告的行为,下游监督仍使用自动进度。工作回顾中的手动操作重新整理所选历史区间。删除计划、报告或到期清理历史不重置来源进度,也不重建图谱。
## 4. 权威入口
| 操作 | 权威入口 | 其他位置 |
| --- | --- | --- |
| 创建或编辑自动监督配置 | 监督者 > 自动监督 > 创建或编辑 Modal | 不复制表单 |
| 选择 Global / Project 范围 | 监督者 > 自动监督 > 创建或编辑 Modal | 不依赖当前项目推断 |
| 暂停、恢复、立即运行或删除 | 监督者 > 自动监督 | 不复制操作 |
| 查看自动监督报告与待处理建议 | 监督者 > 自动监督 | 保留既有结果及处理操作 |
| 查看运行历史和失败 | 监督者 > 活动记录;自动监督 | 活动按同一次执行展示心跳报告和下游监督状态;自动监督页保留报告本身的运行审计 |
| 管理平台级默认值 | 设置中心 | 不显示单条计划 CRUD |
移除重复入口的顺序:
1. 先在智能心跳中支持完整创建、编辑、范围、暂停、恢复、立即运行和删除。
2. 验证旧数据与新范围均可管理。
3. 再从任务中心移除 `HeartbeatSettings`。
4. 再从设置中心移除重复 `HeartbeatSettings`,必要时保留“打开智能心跳”链接。
5. 任一步失败都不得造成用户没有可用配置入口。
## 5. 智能心跳页面
五页签归属以[监督者 UI 设计](../conversation-supervision/ui-design.md#应用入口)为准:自动监督管理计划并显示运行概览、统计、趋势、自动监督报告、建议和 Run 审计,设置只展示算法参数,工作回顾阅读统一监督结果及历史,活动记录只展示统一执行、进度和详情,并支持按计划 ID 筛选。原有 CRUD、建议处理、报告展开及分页能力保留,不在设置内部再建页签。
### 5.1 心跳计划
创建和编辑至少显示:
- 名称。
- `Global` 或指定 Project 范围。
- 每日或每周重复规则;当前不支持分钟间隔。
- 本地时间、星期与 IANA 时区。
- 回顾窗口。
- 保留期限。
- 启停状态。
- 下次运行与上次状态。
交互要求:
- 使用持久标签,不以 placeholder 代替。
- 编辑进入明确状态,支持保存或放弃。
- 保存失败保留草稿。
- 删除继续使用共享破坏性确认。
- 运行中禁用重复操作。
- 保存成功后由计划列表直接反映结果;失败保留草稿并在编辑区就地提示。
### 5.2 范围呈现
- 页面标题不再根据当前 Project 伪装成心跳实际范围。
- 每张计划卡片显示 `Global` 或完整 Project 摘要。
- 多项目过多时显示“项目 A、项目 B 等 N 个”,并提供完整可访问名称。
- 报告成果元数据保存配置冻结范围;计划卡片始终显示计划自身范围,不根据当前项目重新解释。
- 项目失效或删除后,界面准确显示剩余范围或配置已被移除。
### 5.3 响应式与无障碍
- 复用监督者的 `supervisor` 壳层,创建和编辑区域保持单列。
- 窄窗口下计划列表和表单转为单列卡片。
- `Global / 指定项目` 使用共享分段选择控件,Project 多选使用 Checkbox。
- 范围、状态和失败不能只依赖颜色。
- 表单错误与字段程序化关联。
- 对话框或编辑区关闭后,焦点返回触发按钮。
## 6. 数据与安全要求
目标合同只扩展现有心跳范围,不扩展分区记忆合同:
```ts
type HeartbeatScope =
| { kind: 'global' }
| { kind: 'projects'; projectIds: string[] }
```
- 旧 `projectId` 只用于迁移兼容,不继续作为目标范围合同。
- Main 在创建、编辑、列出和执行时验证 Project 归属。
- Global 读取所有 Project 的有界会话和任务,但长期记忆仍只读取 Global。
- 指定 Project 读取选中项目的有界会话和任务,以及 Global 与选中项目记忆。
- 心跳交接、监督分页与输出容量、模型阶段超时、重试和工具禁用边界以[生产接线](../conversation-supervision/review-scheduling-design.md#0-生产接线与剩余边界)及[模型阶段调度](../conversation-supervision/technical-design.md#模型阶段超时与调度)为准。监督模型池不限制普通聊天,不将历史独立报告阶段作为当前必须执行的路径。
- 多项目汇总后统一应用上限,不能按项目倍增预算。
- 心跳结果默认不在系统通知中暴露私人正文。
- 数据迁移必须使用 SQLite 事务,保留外键、级联删除和现有历史。
- 心跳运行失败时,运行记录与配置的 `last_status` 必须在同一 SQLite 事务中
更新;任一写入失败时两者一起回滚,不能留下半提交状态。
## 7. 实施状态与后续顺序
### 已完成:入口和范围
- 扩展共享 Schema、Preload 与 Main 数据合同。
- 增加 Global / 多 Project 持久化与旧数据迁移。
- 让心跳执行按冻结范围构建有界输入。
- 在“监督者 > 自动监督”中完成全部计划操作;创建和编辑使用同一 Modal 表单。
- 补齐范围、迁移、权限和界面测试。
### 已完成:移除重复配置
- 从 Task Center 移除心跳完整表单,保留 Task 和 Scheduled Task 现有行为。
- 从设置中心移除单条心跳 CRUD。
- 如需要,设置中心仅保留“打开智能心跳”导航。
- 验证应用内仍只有一个完整配置入口。
### 后续:分区记忆协同设计
- 按 Global、Project、Automation、Run 和 Agent 分区独立回顾并提出候选。
- 与已确认记忆、候选、心跳报告和建议的关系。
- 时间与内部事件唤起条件及生命周期。
- 与 Task 的关系。
这些内容需要新的 PRD 和明确确认,不属于本轮实现。
## 8. 验收状态
- [x] 监督者的自动监督页签是完整计划配置的唯一权威入口。
- [x] 用户可以创建和编辑 `Global` 心跳。
- [x] 用户可以创建和编辑绑定一个或多个 Project 的心跳。
- [x] 切换当前 Project 不会改变已保存范围。
- [x] Main 拒绝不存在、已归档或超出配置范围的 Project ID。
- [x] Global 与多项目输入遵守现有总上限,不按项目倍增。
- [x] 多项目一次运行只产生一份 Run 和报告。
- [x] 旧 Global 和单 Project 配置无损迁移。
- [x] 旧运行、报告、建议、记忆和任务仍可查看。
- [x] 心跳计划支持创建、编辑、暂停、恢复、立即运行和删除。
- [x] 任务中心不再包含完整心跳配置表单。
- [x] 设置中心不再包含单条心跳 CRUD。
- [x] 任务中心本身以及定时任务现有行为没有被删除。
- [x] 智能心跳仍保持只读、禁用工具和有界输入输出。
- [x] 没有新增平行的记忆类型、表或页面。
- [x] 加载失败、空状态、字段错误和危险操作满足统一设计与无障碍要求。