Files
ycode/docs/三模块开发计划-2026-10-17.md
T

138 lines
18 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.
# 定时任务、资料库、项目:开发准备与执行计划
日期:2026-10-17。本文最初为三个模块的开发准备计划。用户随后授权开发,当前首批本地链路已实现并通过定向与集成验收;实际范围、测试及未完项见[首批开发记录](三模块首批开发记录-2026-10-17.md)。下文计划项不能视为全部已实现。
本计划是当前三个模块的开工入口;安全中心不在本轮。安装中心是此前误解,已经退出范围。目标仍是通过REA对标WorkBuddy的视觉、交互和功能;云端服务与产品侧子代理调度继续暂缓,不能因此把整体标记为完整1:1。
> 新增联动核对:[对话资料沉淀与任务引用确认](对话资料沉淀与任务引用确认-2026-10-17.md)。已确认产物保存的个人/项目目标区分、space-doc+library技能引用、todo及关联附件;默认项目根指针只在已捕获的teams/cloud发送链路证实,本地adapter路径仍待核对。原版并未被证实每轮自动检索全库,不能把此前快照建议当作原版读取语义。
> 新增触发边界:同记录第8节确认todo/plan事件及权威taskList的卡片投影、交接时创建项目事项并后台上传资料、模板阶段提示。会话计划≠项目事项,合成卡片≠模型实际工具调用,生成文件≠资料入库。未证原版统一复杂度拆解阈值或任务终态自动上传hook,开发不自行硬编码这些策略。
## 一、已有基线和开工条件
| 模块 | 当前已有真实能力 | 需要新增或收口 | 原版依据 |
| --- | --- | --- | --- |
| 定时任务 | 会话、模型、空间、OMP、事件广播可复用;没有自动化页面、仓库或调度器 | 定义/规则、表单、持久化调度、真实执行、运行记录和生命周期 | [专项拆解](定时任务模块拆解-2026-10-17.md):5.8.3页面/表单及静态RRULE证据 |
| 资料库 | 工作区文件读取、右栏预览、当前会话产物提取 | 跨任务产物索引、资料库路由、个人资料存储、最近/收藏/搜索与引用 | [专项拆解](资料库模块拆解-2026-10-17.md):5.8.3首页、菜单、骨架、本地产物REA证据 |
| 项目 | 真实list/create/update、模板、任务归属、指令注入 | 现有缺陷、能力配置编辑、真实任务状态、生命周期、动态/计划/资产及联动 | [专项拆解](项目模块拆解-2026-10-17.md):5.8.3列表、新建、详情、任务和CSS证据 |
代码基线有大量已有未提交修改和新增文件;本轮未重置、提交或覆盖这些修改。开发时从当前工作树继续,测试隔离userData、OMP HOME、模型上游,保留用户草稿与已有配置。上一轮通过记录不等于新增功能通过,本轮也不重新运行无改动的全套测试。
## 二、本次代码核对新增的优先问题
1. **对话启动服务需要抽取。** `src/main/ipc.ts` 的`chat:send`主体封在`registerIpc`中,涉及会话锁、运行表、模型/能力快照、OMP、消息检查点、广播和退出回收;`session:create`也封装了项目/空间/模型校验。调度器不能依赖renderer或伪造Electron事件调用IPC。
2. **项目首次发送的失败补偿未覆盖。** `ProjectDetailPage.sendProjectTask`先创建会话,再切页并调用store.send;store只有自己新建的会话才执行空会话清理。因此发送在返回runId前被拒绝时,可能留下空项目任务,详情局部错误也可能已不可见。
3. **项目运行标识查错键。** `ProjectDetailPage`用`runs[task.id]`查运行态,但chat store按runId存储runs,所属sessionId在值里。任务可能被错误显示为非运行/成功。
4. **项目状态筛选未生效。** `taskStateFilter`虽更新但不参与tasks过滤;不能把“没有在运行”全部认作成功,必须由真实持久化回合状态派生。
5. **详情内保存指令后未更新父列表对象。** 详情保存只调用projects.update并关闭抽屉;父ProjectListPage持有的project对象没有更新,和列表自己的保存逻辑不同,详情文字会停留在旧值。
6. **资料库索引不能由目录扫描代替。** `workbench-state.collectWorkbenchArtifacts`只聚合当前会话;必须把有来源的产物提取复用到主进程,不能把整个项目源码或用户输入附件都算作产物。
以上为源码观察,未在本轮运行缺陷复现;开发时须加对应真实失败场景或状态回归再修复。
## 三、主上下文统一的契约与实现边界
### 3.1 会话与执行服务
计划新增`src/main/chat-turn-service.ts`和`src/main/session-factory.ts`:
- `createManagedSession(context)`集中处理项目、空间、cwd、模型、专家和模式校验;共享现有仓库实例。
- `startChatTurn(payload, origin)`提供普通IPC和自动化共用入口;保留现有对外SendResult,服务内部另外提供run完成Promise和取消/查询能力。
- 终态必须在消息持久化完成后才认定;保存失败不能写成自动化成功。服务释放、取消、会话锁与运行恢复语义保持原有行为。
- 广播端口可注入,后台启动没有sender也能正常执行;renderer仍通过现有IPC订阅,调度器直接调用服务。
- 这是有限抽取,不重写OMP/Gateway,不顺带改消息投影、编辑回退或跨窗口事件算法。抽取后必须先过现有对话回归。
### 3.2 实体关系与存储
以下为YCode工程决策,不是原版后端还原:
| 实体 | 最低字段与关系 | 约束 |
| --- | --- | --- |
| AutomationDefinition | id、revision、名称/提示词、schedule、execution、启用/归档、可选workspaceId/projectId | 修改不覆盖历史运行快照;不与普通session混为一个实体 |
| AutomationRun | runId、definitionId/revision、trigger、scheduledFor、sessionId、起止、状态/错误和执行快照 | 每个触发实例有稳定去重键;执行记录终态来自实际会话服务 |
| LibraryNode | nodeId、collectionId、parentId、kind、标题、受管内容引用、version/hash、时间 | renderer只提交ID;个人资料由主进程在独立受管根读写 |
| ArtifactIndexEntry | id、workspaceId/projectId、sessionId/messageId、来源类型、文件/预览引用、时间和可用状态 | 同任务同路径以最新产物汇总;跨任务保留独立来源,此规则为本地设计待原版复核 |
| LibraryReference | 引用种类、来源ID/URL、标题/类型、原版元数据、可取得的版本和解析结果 | 保留space-doc/project-assets/todo语义;本地快照为适配建议,云资料版本与读取时机待证,不伪造已读取 |
| ProjectAssetLink | projectAssetId、projectId、显式来源链接 | 与LibraryNode分开,具体管理/引用UI先补REA,不直接把资料库节点当项目资产 |
| ConversationPlan / ProjectTodo | 前者从会话工具/plan事件维护;后者有projectId及真实项目创建/状态/附件操作 | 独立身份、显式关联;不能看到TodoWrite就伪造项目事项已创建 |
- 工作空间、项目、资料集合使用不同ID与生命周期。项目任务的project/workspace/cwd沿用现有校验;项目工作空间仍不可直接修改。
- definitions/runs需要事务一致的本地持久化边界,第一版放同一版本化仓库并序列化原子提交;不把定义写一半、记录写另一半。
- 个人资料使用`userData/library/`受管目录,元数据和文件两阶段提交并处理失败补偿;具体文件名对外不作为节点ID。
- sessions新增归属字段须可选、兼容旧历史;主进程验证自动化/项目来源,不能由任意renderer值改变执行权限。
- shared类型分别放`automation.ts`、`library.ts`、`artifact-index.ts`;现有`projects.ts`原地扩展。IPC采用automation/library/projects分域;preload、主进程注册和页面路由由主上下文集成。
### 3.3 调度第一版的明确策略
为了能写出可验证的第一版,下列策略作为**YCode本地开发基线**;原版时区/DST/重试/漏跑未证实,后续通过REA核对后再调整,不能按这些策略宣称原版等价:
- 创建时保存明确的IANA时区与用户规则,下一触发时间用UTC;时间计算为纯函数,可注入时钟。RRULE保留原版已知语法,成熟库的时区行为须专项核验,不能用固定24小时毫秒代替日历周期。
- 同一任务不重叠;计划触发与手动触发经过同一领取/执行入口,队列和去重在主进程。全局并发受控,先保证多模型/多项目不串配置。
- 周期漏跑先记录并跳过,一次任务过期不自动执行;默认不自动重试。异常退出的历史运行核对实际会话后记中断/未知,不未经核对重发模型请求。
- 明确区分暂停、过期、归档、删除和取消运行。运行中触发/删除遵循已有原版静态拒绝分支;编辑是否影响当前run由快照隔离。
- 首版调度随主进程运行;关闭应用后仍执行需要额外后台或系统调度支持,当前未实现、原版行为待证。不能因窗口关闭策略不明而宣称关应用后也会执行。
### 3.4 产物、个人资料与引用
- 共用纯提取器从显式artifact、成功present_files和成功写/编辑事件提取产物;读取工具输出、附件、任意目录文件不自动计入。
- 历史回填和新回合增量共用同一规则;索引是可重建的派生数据,不反写会话原文。归档仍保留来源;删除后按事实清理/标不可用,不误删工作目录文件。
- 打开产物带sourceSessionId,按来源cwd校验;资料库个人文件用nodeId解析受管根,不扩大现有resources:read权限。
- 导入通过主进程文件选择与复制,先临时写/计算大小及hash,再提交节点;失败不能留半个可见文件。
- 不把library ID塞进现有resources:string[]路径字段。新增reference结构贯通SendPayload、ChatMessage、落盘、编辑回退和两种模型历史通路;旧消息不受影响。新增主进程引用解析层,保留原版资源身份与技能/待办元数据,再装载当前实现确实能读取的内容;不得仅画chip却不传资源。
- 个人/项目资料保存目标遵循实际会话归属和权限,和本地产物索引分开;原版工具栏项目会话提供项目资产路径而非个人库路径。每次成功生成文件不等于云端入库,整段聊天也没有已证自动入库规则。
- 项目资料scope、用户显式引用、模型实际读取分开记录;不静默把个人或其他项目全库作为默认上下文。原版本地默认scope和自主检索仍须REA补证,teams/cloud根指针逻辑不能直接外推。
## 四、可直接派发的开发任务
下列路径中的新增文件/命令是计划,不表示当前已存在。每个子任务结束报告文件、设计、验证与遗留;共享文件只由主上下文接线,跨模块依赖通过接口交付。
| 编号/负责人 | 文件边界与任务 | 验收出口 |
| --- | --- | --- |
| C1 主上下文 | `chat-turn-service.ts`、`session-factory.ts`、`main/ipc.ts`、`main/index.ts`:抽取公共执行和生命周期 | 原IPC行为不变;没有renderer也可启动并等待真实持久化终态 |
| C2 主上下文 | shared IPC/types/workspaces、preload、App/Sidebar、chat store、package.json:契约、路由、事件与集成 | 旧数据兼容;新页不破坏草稿/多窗口;API有统一失败语义 |
| C3 主上下文 | 新`shared/context-references.ts`与`main/context-resolver.ts`:资料/todo/项目资产引用及作用域解析,供对话/自动化共用 | 来源与scope正确;显式引用进入实际请求;失败可见;不能将根指针标作全部文档已读取 |
| S1 定时任务agent | 新`main/automations/{repository,schedule}.ts`、`shared/automation.ts`(先经主协调冻结) | 定义/run持久化、七类规则、可控时钟与损坏恢复;失败不清空数据 |
| S2 定时任务agent | 新`renderer/src/automations/**`:列表/记录、模板、新建/编辑和规则控件 | 使用REA已有CSS/图标/文案;真实CRUD、重载;未接通知状态真实 |
| S3 定时任务agent | 新`main/automations/{scheduler,runner}.ts`,消费C1端口 | 到期→领取→实际会话→终态→记录;单飞、重启、漏跑和取消可测 |
| S4 定时任务agent | 记录/启停/手动运行/编辑/删除/归档与项目入口 | 操作和持久化状态一致;记录可打开正确会话;原版缺失状态补REA |
| L1 资料库agent | `shared/artifact-index.ts`、新`main/library/artifact-index.ts`;原提取器改动经主协调集成 | 跨任务正确索引;去重、来源、失效与归属;不扫描源码冒充产物 |
| L2 资料库agent | 新`renderer/src/library/**`与store:内侧栏、最近、本地产物、排序/筛选/收藏 | 原版已有布局直接应用;可打开实际产物;长列表/空/错误可用 |
| L3 资料库agent | 新`main/library/{repository,service}.ts`、`shared/library.ts` | Markdown/CSV/文件夹/链接及导入真实落盘,原子补偿,重启恢复 |
| L4 资料库agent | 搜索、预览/编辑、引用选择与快照;消费C2引用契约 | 请求内容和显示来源一致;历史/编辑/重载不丢引用;编辑器先补REA |
| P1 项目agent | 现有`renderer/src/projects/**`及专项脚本:先修首发补偿、运行点、状态筛选和指令保存同步 | 真实失败不留孤立空任务;进行/完成/失败按事实;详情即刻反映配置 |
| P2 项目agent | 列表/新建/详情壳、指令/能力配置、`main/projects.ts`与`shared/projects.ts` | 可创建、查看、修改、重载;市场引用不冒充已安装能力;配置是否作用执行要另证 |
| P3 项目agent | 项目生命周期、任务行/来源过滤、交接创建待办与附件关联、恢复与配置事件 | 菜单/副作用先补证;交接事项创建与附件上传状态分别留证,部分失败可恢复;不误删会话或目录 |
| P4 项目agent | 动态/计划/资产与S/L模块关联;新增子域先主协调定契约 | 逐页补REA后接真实本地数据;项目/资料/自动化引用可追溯,云成员协作仍单列未接 |
项目指令、专家、技能、连接器的继承/优先级必须核对原版,不自动把项目内所有专家一起激活。现有buildProjectPrompt只证明指令注入,保存能力ID不等于能力在任务中生效。
## 五、执行顺序与每批可见结果
1. **基础批**:主上下文先做C1/C2/C3的最小契约、执行抽取与引用解析边界。并行agent可做S1纯仓库/时间引擎、L1产物提取与索引、P1独立页面修复;不得并行重写同一chat store或IPC。
2. **第一批可用结果**:定时任务至少一次/每日的真实执行和记录;资料库可浏览实际跨任务产物并打开;项目可创建/编辑指令/真实发起任务,首发失败可恢复。已完成状态的UI从这一批就按原版证据实现,不等全部逻辑完成才做视觉。
3. **第二批完整本地链**:补齐其余频率及生命周期、个人资料与引用、项目配置和任务操作;分别做隔离Electron+受控模型回归。第一批的频率切片不作为缩减完整七类频率范围的决定。
4. **第三批页面与关联收口**:补REA后推进资料编辑/导入细节、项目动态/计划/资产及跨模块联动;云协作/远端推送/服务端权限保留独立未接清单。
5. **最终对照**:逐状态验证几何/字体/图标/滚动/菜单/动效、深浅色与窄窗口。视觉、交互、真实功能分别留证;没有证据或没有实现的项保持未完成。
## 六、验证安排
| 变更 | 必须保留的既有验证 | 需要新增的有意义验证 |
| --- | --- | --- |
| C1/C2对话与归属 | `npm run typecheck`、`test:conversation-ipc`、`test:chat`、`test:persistence`、`test:sessions`;集成后`test:omp-session`、`test:task-window` | 主进程直接启动、无窗口、成功/失败/取消、完成Promise和磁盘终态一致;项目首发补偿与草稿恢复 |
| 定时任务 | 共用对话回归及相关UI检查 | 假时钟七类频率/月底/闰年/时区、单飞/领取竞争、重启/漏跑;受控上游实际产生会话与run记录,保存失败不能成功 |
| 资料库 | `test:resources`、`test:artifacts`、`verify:previews`、`test:sessions`;引用变更跑对话持久化 | 来源白名单/历史回填/增量一致、失效文件、跨会话打开、导入失败补偿、伪造nodeId/符号链接;实际模型wire history引用快照 |
| 项目 | `node scripts/verify-project-storage.cjs`、`node scripts/verify-project-page.cjs`、相关对话IPC专项 | 首发拒绝不留空任务、状态筛选/运行点、指令保存即时更新、能力选择持久化、空间/项目隔离、跨窗口更新 |
| 集成与视觉 | 一次最终`npm run build`后串行运行相关Electron专项 | 同数据/视口/主题的REA对照截图和状态序列;明确动态区域、误差与缺口 |
新增测试名称由实现时登记,不能把计划中的脚本写成已通过。Electron专项由主上下文串行运行,agent只在各自目录执行纯逻辑测试,避免窗口/端口和用户数据冲突。
## 七、不会阻塞第一批与必须补证的部分
- 第一批可直接推进:本地仓库、执行服务抽取、定时任务已知表单/规则、产物索引、已有项目缺陷与指令保存。它们有明确数据通路或既有原版证据。
- 与开发并行补REA:频率/有效期弹层、任务与记录有数据状态,资料搜索/导入子菜单/编辑器,项目筛选枚举/任务菜单/能力选择/动态计划资产页面。
- 阻止宣称1:1、但不阻止首批开工:原版后端时间语义、云资料和成员权限、远端通知、全状态像素与动效未验收。
- REA运行态采集统一调度,避免多个agent操作同一个原版窗口。沿用5.8.2有效证据;缺失部分的新采集注明真实版本与Evidence ID,不改用其他通道。
## 八、本轮交付状态
已从准备转入开发:C1/C2 执行服务与路由、S1/S2/S3 的首批本地实现、L1/L2 本地产物浏览、P1 及能力配置编辑已落地,新增 `rrule` 依赖。首批真实模型/工具/Electron 链路已验证;C3、个人资料导入/引用、项目待办/资产/动态/完整生命周期及全状态 1:1 仍未完成。具体以[首批开发记录](三模块首批开发记录-2026-10-17.md)为准,不能把计划表中的全部功能勾为完成。