Skip to content

CI: pin the dsh-schedule private task shape the delivery board moves (#1245) #1257

Closed

Description

@Birfy

Owner: 待派(Lead 定)

#1249(修 #1245)让 moveSchedules 第一次去碰 DSH 的私有存储面:service.serialize() 里拿 (await service.getDomain()).table('tasks'),直接改写行 { ...task, sessionId: toId }。这条路是承重件——握手时任务能不能跟过来全靠它——但没有任何测试盯着它的形状。DSH 侧一改名或改形状,它不会红,只会静默停摆。

事实(本机 @deepseek-ai/dsh-schedule 0.2.1-rc.2,2026-10-26T06:4xZ 读)

  • 两个成员在类型声明里就是 private:lib/types/index.d.ts:125 private getDomain;、:151 private serialize;(相邻的 :124 private emitChanged; 同样是 private)。
  • 实现:lib/index.js:2238 async getDomain()、:2293 serialize(work);table('tasks') 的行形状 { sessionId, record, status, deliveryHistory }。
  • 版本是精确 pin:dsh-api-remotes、dsh-client-ui-schedule、dsh-client-ui-workspace、dsh-tool-schedule 四个包都写 "@deepseek-ai/dsh-schedule": "0.2.1-rc.2"(不是 range)。所以升级是一次显式动作——但升级时不会有任何东西提醒我们这条路可能已经废了。
  • 本仓没有把它声明成依赖(package.json / core/package.json / ds-bot/package.json 里都没有),它是宿主注入的 service。

口径更正:交办里写的是 0.2.0-rc.2 与 d.ts:119/:132;实测是 0.2.1-rc.2、:125/:151。按实测走。

失败形状(静默,不崩)

DSH 改名或改行形状 → service.serialize / service.getDomain 不存在或返回的形状变了 → moveSchedules 里抛错 → 外层 catch 只留一行 rt.warn('ds-bot: tasks of %s not moved: %s', fromId, …) → 任务留在正在被归档的旧 part 上,归档路径照样 stopActivity(#896 那条:core/test/part-archive.test.js 的 #896: a failed task move does not leave an armed earlier part active 断言"移动失败也不留一个 armed 的旧 part")→ 任务从此不再触发,界面上没有任何红。

更糟的是测试本身也照抄了这个形状:#1249 给 core/test/schedules.test.js 与 core/test/part-archive.test.js 的内存 fake 都加了 getDomain() / serialize(),字段也写成 { sessionId, record, status, deliveryHistory }。fake 与真模块同时改,所以现有用例抓不到 DSH 改名——绿的是 fake 自洽。

要的验收

  1. 一条对真模块(不是 fake)的断言:getDomain 与 serialize 存在且是函数,table('tasks') 可读,行字段齐 sessionId、record、status、deliveryHistory(record 里至少 id、title、kind、scheduledAt)。
  2. DSH 一改名/改形状,这条必须红,而不是跳过——skip 不算钉住。所以它得跑在真能 import 到 @deepseek-ai/dsh-schedule 的地方(宿主/打包侧检查,而不是 core/ 的常规单测环境);落在哪由 owner 定,但"环境里没有就 skip"不满足验收。
  3. 失败信息要点名「getDomain/serialize 在 0.2.x 上是 private,升级 DSH 时要重新确认 moveSchedules 的这条路径」,让下一个人不用重查。

关系

  • 与 #1248(「承重但没钉住」)同类,互不重复:#1248 钉的是 review-gate 的引用块护栏,本单钉的是 DSH 私有形状。
  • 不阻断 #1249。#1249 的 PASS 只要求把这条风险写进结论,并在 docs/subsystems/core-host.md 里留话——那份 diff 已经加了「Part move」一段(写明靠 service.serialize 改存储域里那一行),满足。
  • 与 #1245(任务重新锚定)、#896(归档竞态)不重复:那两条是行为,这条是"行为的底座没有测试"。

不做

  • 不改 moveSchedules 的行为、不动 #1249 的代码;
  • 不把 @deepseek-ai/dsh-schedule 加成本仓依赖;
  • 不删现有 fake——行为测试继续用 fake(它们测的是 FlyBot 自己的逻辑),本单只加一条盯真模块的钉;
  • 不为此加 CI 矩阵或新 workflow,能找到现成的宿主侧检查点就挂在那里。

Activity

  1. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:automationScheduled tasks and automation
    on Oct 26, 2026
  2. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Owner: Dev (Lead decision)

    Dev owns this after #1256 merges — both touch the same host task path (core/src/host/tasks.js, core/src/host/task-drive.js), so they do not run in parallel.

    Shape to pin, from the issue body: moveSchedules reaches the row through (await service.getDomain()).table('tasks') and rewrites { ...task, sessionId: toId }. The test must fail when that row shape or either private method (getDomain, serialize) disappears, not only when moveSchedules throws — today the outer catch in parts.js turns a rename into one rt.warn and the task is simply left on the archived part.

  3. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Claimed-by: Dev

    Branch: dev/feat/1257-dsh-task-shape @ 65fe284c6c47debf7efc38ff94cd74dfb68e5b7f, one commit on main 4095e1359a5a023c8e5d5ffb7ac7f8ff484f7c31 (branch re-cut onto it; the earlier cut was off 98528d9f and is superseded). Two files, +160/−0, both under .github/ — no core/, so no patches/ds-bot/ regeneration.

    What it will pin, from the issue body: moveSchedules rewrites a task row through service.serialize(...) and (await service.getDomain()).table('tasks') and puts { ...task, sessionId: toId } back. Both members are private on dsh-schedule 0.2.x, and the row belongs to a storage domain declared inside the package, so a rename does not throw anywhere a test can see.

    Red plan (each alone, module mutated, check must exit 1):

    1. getDomain renamed → ScheduleService.prototype.getDomain is not a function.
    2. row member renamed (sessionId → session) → the row moveSchedules writes is refused by the schema, naming the key.
    3. serialize renamed, status value renamed, and the package absent → one line each, the last one failing rather than skipping.
  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    and removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 26, 2026
  5. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:automationScheduled tasks and automationbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions