scheduler-gateway/docs/TASK-SUBMISSION-CONTENTS.md
Liuxinyu176 bbb364cd69 feat: DSH 调度网关(互联网关)v6.0.0 — 四模型合并版 R1+R2+R3
- 零第三方依赖,Node >=20 原生 ESM
- 团队式编排引擎:拆解/路由/执行/审查/合并全真实 LLM
- 阶段心跳、单一权威清单守卫、all-keys-failed 如实上报
- H4 会话视图/amend/watchdog 有界重试/产物区 artifacts.json
- H5 零依赖三栏控制台
2026-10-09 23:20:27 +08:00

391 lines
16 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.

# 众测任务创建表单内容
---
## ① 众测框架选择
**选择:云端 Claude Code**
---
## ② 任务标题
```
调度网关 P0 生产化基线加固(状态机/Repository/幂等/取消/死信/回调/事件/健康检查/测试,共11项任务)
```
---
## ③ 首轮 Prompt
```
你正在参与 scheduler-gateway-epoch 6.0.0 的第一阶段 P0 生产化基线开发。
## 项目背景
这是一个 DSH 调度网关:中心网关 + 任务队列 + 节点协议(gw-node/1)+ 真实 LLM 多智能体编排(planner→workers→reviewer→merger)。当前是可演示、可验收的单机原型,需要工程化加固为可长期运行、可恢复、可审计的执行平台。
项目特点:Node.js >= 20,原生 ESM,零第三方运行时依赖。
## 必读文件
开工前必须先阅读以下文件,确认现有行为后再修改:
- README.md — 项目总览与快速开始
- ARCHITECTURE.md — 架构与协议
- IMPLEMENTATION.md — 实现细节与验证方式
- ADR.md — 关键决策记录
- PHASE-1-UNIFIED-TASK.md — 完整任务书(你的主要参考)
- src/server.js — HTTP 网关、节点协议、任务 API
- src/store.js — 任务/节点/审计/事件存储
- src/scheduler-core.js — 调度、领取、结算、重试、死信
- src/protocol.js — 状态常量、节点协议、鉴权
- src/wal.js — JSONL WAL
## 技术约束(必须遵守)
1. Node.js >= 20,原生 ESM,零第三方运行时依赖
2. 保持现有 API 兼容,不破坏既有接口语义
3. 保持 REAL/OFFLINE/fixture 诚实标记
4. 不得泄漏任何密钥(key/token/password/secret)
5. 不得修改 归档-*、out、work、evidence 中已有历史产物
6. 不得通过任意 task.state = ... 绕过状态机
7. 不得通过放宽断言、增加无限重试、忽略异常来制造全绿
8. 新增模块优先放在 src/domain、src/application、src/adapters、src/platform
9. 先包裹旧实现,再逐步迁移调用方;不要一次性重写 server.js 或 orchestrate.js
## 需要完成的 11 个任务
### 任务 A:任务状态机
新增 src/domain/task-state-machine.js:
- 定义当前任务所有合法状态和迁移(queued/running/done/succeeded/failed/dead/rework/waiting_approval/canceled)
- 提供 canTransition(from, to)、transition(task, to, context) 等接口
- 迁移失败抛出稳定错误码 INVALID_STATE_TRANSITION
- 迁移时追加历史记录(操作者/原因/时间/attemptId/requestId)
- 将 server.js、store.js、scheduler-core.js 中直接修改状态的关键路径迁移到状态机
- 重复 settle、过期 lease settle、已取消任务回报等场景必须拒绝或转为幂等成功
### 任务 B:Repository 抽象
新增 src/domain/repositories.js + src/adapters/storage/file-repository.js:
- 至少抽象任务、节点、事件、审计、死信和产物索引访问
- 现有 GatewayStore 可作为兼容实现,但业务服务不得继续依赖 Map 的内部结构
- 保留 persist:false 的干净内存测试模式
- 保留现有 JSON 落盘和 WAL 能力
- Repository 方法必须区分"找不到""冲突""非法状态""存储失败"
- 为未来 SQLite/PostgreSQL 实现保留异步接口
### 任务 C:幂等键和租约
- 创建任务支持 Idempotency-Key;重复请求返回同一任务
- claim 生成唯一 leaseId,记录 leaseExpiresAt、nodeId、attemptNo
- settle 必须校验 lease;重复提交同一 leaseId + 相同结果幂等返回;不同结果拒绝并审计
- lease 过期后任务可重投,但旧节点迟到回报不得覆盖新结果
- retry、cancel、approve、amend 具备幂等行为
- 不得用进程内 Map 作为唯一幂等数据来源
### 任务 D:统一错误、审计和请求关联
- 新增稳定错误码集合(INVALID_ARGUMENT / TASK_NOT_FOUND / INVALID_STATE_TRANSITION / LEASE_NOT_FOUND / LEASE_EXPIRED / IDEMPOTENCY_CONFLICT / TASK_ALREADY_TERMINAL / STORAGE_ERROR / REVISION_CONFLICT)
- 每个 HTTP 请求生成或透传 X-Request-Id
- 每个任务运行生成或透传 runId、taskId、attemptId、nodeId
- 审计记录至少包含:时间、动作、对象、结果、操作者/来源、requestId、runId、错误码
- API 错误统一为 { error: { code, message, requestId, details } }
- 保持现有接口状态码兼容
### 任务 E:健康检查和配置校验
新增 src/platform/config.js + src/platform/health.js:
- 统一读取端口、host、数据目录、WAL、节点 token、TLS、LLM provider 和超时配置
- 新增 gateway check 或等价检查命令
- 新增 /healthz(进程存活)和 /readyz(数据目录/WAL/Repository 可写性、必要配置)
- 生产模式检测到默认节点 token 时必须给出明确警告;安全模式可直接拒绝启动
- 检查结果必须脱敏
### 任务 F:补齐测试和验证脚本
新增或扩展测试:
- 状态机:合法迁移、非法迁移、重复终态、取消竞态
- Repository:内存态、文件态、WAL 开关、损坏文件、恢复后读取
- 幂等:重复创建、重复 claim、重复 settle、冲突 settle、过期 lease
- 故障:进程中断、节点掉线、旧节点迟到回报、回调失败、磁盘不可写
- 安全:错误响应不泄漏密钥,requestId 和审计不泄漏敏感字段
- 回归:现有 npm test、npm run test:conversation、npm run e2e-team 能继续运行
### 任务 G:任务版本与乐观锁
- 每个任务带 revision(整数,初始 1),每次 transition/settle/update 成功后自增
- transitionTask、settleTask、updateTask 必须接受 expectedRevision;不匹配返回 REVISION_CONFLICT
- 重复提交相同 leaseId + 相同结果时,revision 不变,幂等返回当前终态
- 不同结果或不同 attemptId 的 settle 必须因 revision/lease 校验失败而拒绝
- revision 必须随任务持久化,重启后恢复
- 审计记录每次 revision 变化
### 任务 H:事件持久化与 SSE 重连
- 事件通过 EventRepository 持久化(FileRepository 先落 JSONL)
- 每个事件带 seq(全局递增)、type、aggregateId、revision、at、requestId
- SSE 支持 Last-Event-ID:客户端断线重连时从 Last-Event-ID + 1 开始补播
- 事件保留期可配置(默认 7 天或 10000 条)
- 进程重启后 seq 必须继续递增,不能回退
### 任务 I:回调机制加固
- 回调必须有 HMAC-SHA256 签名:X-Signature: t=<timestamp>,v1=<hmac>
- 回调失败按指数退避重试(至少 3 次:1s / 5s / 30s);全部失败后进入回调死信队列
- 回调必须幂等:接收方可用 X-Callback-Id(= taskId)去重
- 回调 payload 必须包含 taskId、runId、state、revision、result、finishedAt
- 密钥不得出现在日志、审计、导出或错误消息中
### 任务 J:任务取消传播
- cancel 必须将取消信号传播到持有当前 lease 的执行节点
- 取消后任务进入 canceled 终态;执行节点的迟到回报在任务已 canceled 时必须被拒绝
- 如果任务有子任务(parentRun / dependencies),取消父任务时必须级联取消未完成的子任务
- 取消操作本身必须幂等:对已 canceled 的任务再次 cancel 不报错
- 取消必须审计:记录谁取消、为什么取消、取消传播到了哪些子任务
- 如果节点不在线或取消信号投递失败,任务仍应进入 canceled 终态(取消不依赖节点确认)
### 任务 K:死信队列加固
- 每条死信记录必须包含:deadLetterId、taskId、originalTaskId、deadReason、retryCount、firstDeadAt、lastDeadAt
- 死信重投有上限:maxDeadRetries(默认 3);超过后标记 exhausted
- exhausted 死信只能通过人工 POST /api/deadletter/:id/force-retry 重投,且必须记录操作者
- 死信队列支持按 deadReason / retryCount / originalTaskId 查询
- 死信重投必须生成新的 attemptId 和 leaseId,不能复用旧 lease
- 死信归档:exhausted 超过保留期后自动归档
## 验收标准
### 功能验收
- [ ] 所有关键状态迁移经过统一状态机
- [ ] 业务层不再直接依赖 GatewayStore 的内部 Map 结构
- [ ] create/claim/settle/retry/cancel/approve 支持幂等或冲突检测
- [ ] 任务拥有 leaseId、leaseExpiresAt、attemptId 等执行关联字段
- [ ] 旧 lease 的迟到回报不能覆盖新 attempt
- [ ] /healthz、/readyz 和配置检查可用
- [ ] 错误响应包含稳定错误码和 requestId
- [ ] 审计能够还原一次任务从创建到终态的完整过程
- [ ] 任务带 revision,并发 settle 只有一个成功,REVISION_CONFLICT 正确返回
- [ ] 事件持久化到 Repository,SSE 断线重连后能补播断线期间的事件
- [ ] 回调有 HMAC 签名、失败重试 3 次、全部失败进死信队列
- [ ] 取消信号传播到执行节点,已取消任务的迟到回报被拒绝,子任务级联取消
- [ ] 死信带 retryCount/originalTaskId/deadReason,超过 maxDeadRetries 标记 exhausted
### 回归验收
所有命令退出码为 0:
npm test
npm run test:conversation
npm run e2e-team
npm run recovery-demo
npm run stress
### 性能验收
- 在现有压测规模下,任务无重复领取、无永久丢失、无重复终态
- 新增状态机、Repository、审计后,现有 stress 测试吞吐下降不超过 10%
- 必须提供改造前后的 baseline 对比数据:吞吐(task/s)、P95/P99 排队延迟、P95/P99 执行延迟、重复领取数、丢失任务数
- 事件持久化不能阻塞调度主路径
### 安全验收
- 错误、审计、状态、导出、日志中均不存在 key/token/password/secret 明文
- 默认 token、非法路径、非法状态、伪造 lease、越权 settle 均有拒绝结果
- 不引入新的 shell 拼接、动态代码执行或不受限文件路径
## 交付物格式
每个模型必须提交以下内容:
1. 修改文件清单
2. 实现摘要
3. 状态迁移表
4. Repository 接口说明
5. 幂等和 lease 语义说明
6. 测试命令与实际结果
7. 未完成项和已知风险
8. 与其它模型合并时的冲突点
禁止只提交"已完成""测试通过"等无证据结论。
## 执行步骤建议
1. 先读 README.md、ARCHITECTURE.md、IMPLEMENTATION.md、ADR.md、PHASE-1-UNIFIED-TASK.md
2. 读 src/server.js、src/store.js、src/scheduler-core.js、src/protocol.js、src/wal.js,理解现有任务生命周期
3. 按以下顺序实现:状态机(A) → 错误码(D) → 版本乐观锁(G) → Repository(B) → 事件持久化(H) → 幂等lease(C) → 取消传播(J) → 回调加固(I) → 死信加固(K) → 健康检查(E) → 测试(F)
4. 每完成一个任务,运行 npm test 确认没有回归
5. 全部完成后运行回归验收的 5 条命令,记录实际退出码
6. 按交付物格式提交结果
注意:你是四个并行模型之一,使用完全相同的任务书。你的目标是提交可合并代码。保持 Node >=20、零第三方运行时依赖、REAL/OFFLINE 诚实标记和现有 API 兼容。不得修改归档目录,不得删除用户已有改动,不得泄漏任何密钥。完成后必须运行对应测试,报告实际命令、退出码、修改文件和剩余风险。
```
---
## ④ Rubrics 描述
```
## 评估维度与判定标准
### 1. 功能完整性(权重 30%)
优秀:
- 11 个任务(A-K)全部实现并接入真实任务路径
- 所有功能验收项(13 项)全部通过
- 状态机覆盖所有合法/非法迁移,重复终态和取消竞态正确处理
- Repository 抽象完整,业务层不再依赖 Map 内部结构
- 幂等和 lease 在并发、重复、过期场景下行为正确
- 事件持久化 + SSE 重连正常工作
- 回调有签名、重试、死信
- 取消传播到节点和子任务
- 死信有 retryCount/上限/归档
合格:
- 核心任务(A/B/C/D)完成,其余任务部分完成
- 主要功能验收项通过,少数边缘场景未覆盖
- 代码可运行,测试大部分通过
不合格:
- 关键任务(状态机/Repository/幂等)未实现或未接入
- 功能验收项超过 3 项不通过
- 代码无法运行或测试大面积失败
### 2. 代码质量(权重 20%)
优秀:
- 新增模块结构清晰(domain/application/adapters/platform 分层)
- 函数职责单一,命名清晰,注释充分
- 错误处理完善,不吞异常
- 与现有代码风格一致(ESM、零依赖)
- 没有死代码、重复代码或过度工程
合格:
- 模块结构基本合理,有少量设计瑕疵
- 命名和注释基本到位
- 错误处理覆盖主要路径
不合格:
- 模块结构混乱,职责不清
- 大量复制粘贴或死代码
- 异常被静默吞掉
- 引入了第三方运行时依赖
### 3. 测试覆盖(权重 20%)
优秀:
- 每个新增功能都有对应测试
- 测试覆盖正常路径、边界条件、错误场景
- 并发和竞态场景有专门测试
- 现有测试全部通过(npm test 等)
- 新增测试覆盖状态机、Repository、幂等、lease、取消传播、死信加固、事件持久化
合格:
- 主要功能有测试覆盖
- 现有测试基本通过(允许少量已知 flaky)
- 边界场景覆盖不完整但有计划
不合格:
- 没有新增测试
- 现有测试被破坏
- 通过放宽断言或删除测试来制造全绿
### 4. 兼容性(权重 15%)
优秀:
- 现有 API 完全兼容,不改变接口语义
- 现有测试(npm test / test:conversation / e2e-team / recovery-demo / stress)全部通过
- 现有面板、插件、看板桥和团队编排功能未被破坏
- WAL 和持久化行为保持兼容
合格:
- 现有 API 基本兼容,有少量非破坏性变化
- 现有测试大部分通过
不合格:
- 破坏现有 API 语义
- 现有测试大面积失败
- 面板、插件或团队编排功能被破坏
### 5. 安全性(权重 15%)
优秀:
- 错误、审计、状态、导出、日志中均不存在 key/token/password/secret 明文
- 默认 token 检测和警告到位
- 非法路径、非法状态、伪造 lease、越权 settle 均有拒绝结果
- 回调签名(HMAC)正确实现
- 不引入新的 shell 拼接、动态代码执行或不受限文件路径
合格:
- 主要安全检查到位
- 密钥脱敏基本覆盖
- 个别安全场景未覆盖但有计划
不合格:
- 密钥泄漏到日志/审计/导出
- 默认 token 在生产模式下不警告
- 缺少基本的安全校验
### 综合判定
- 优秀:5 个维度均为优秀或合格,且至少 3 个为优秀
- 合格:5 个维度均为合格及以上,且不超过 2 个为不合格
- 不合格:任意 2 个及以上维度为不合格
```
---
## ⑤ 上传附件(Workspace)说明
### 必须上传的文件/目录
```
src/ 所有源码(含 src/nodes/、src/taskboard/、src/team/)
test/ 所有测试(含 test/fixtures/)
web/ Web 面板
scripts/ 工具脚本
lib/ DSH 插件封装
package.json
README.md
ARCHITECTURE.md
IMPLEMENTATION.md
ADR.md
PHASE-1-UNIFIED-TASK.md
DEVELOPMENT-ROADMAP.md
cordis.patch.yml
.env.example
.gitignore
gateway POSIX 启动器
gateway.cmd Windows 启动器
```
### 不要上传的
```
node_modules/ 零依赖项目不需要
out/ 运行产物,可重新生成
evidence/ 运行证据,可重新生成
work/ 工作目录,可重新生成
state/ 运行时状态
归档-* 归档目录,任务不需要
.env.live 含 API 密钥,禁止上传!
_*.mjs / _*.js / _*.html / _*.txt 临时脚本
*.docx / *.png 大二进制文件
_merge_work/ 合并工作目录
```
### 打包建议
把项目根目录下需要上传的文件/文件夹打成一个 zip,保持原始目录结构:
```bash
# 在项目根目录执行
zip -r workspace.zip src/ test/ web/ scripts/ lib/ \
package.json README.md ARCHITECTURE.md IMPLEMENTATION.md \
ADR.md PHASE-1-UNIFIED-TASK.md DEVELOPMENT-ROADMAP.md \
cordis.patch.yml .env.example .gitignore gateway gateway.cmd
```
然后上传 workspace.zip 作为 Workspace。