991 lines
26 KiB
Markdown
991 lines
26 KiB
Markdown
# Yonexus — TASKLIST
|
||
|
||
基于 `FEAT.md`、`PLAN.md`、`PROTOCOL.md`、`README.md` 整理。
|
||
|
||
目标:把 Yonexus 从“规划完成、实现未开始”的状态,拆成可逐项交付、可验收、尽量低耦合的小任务列表。
|
||
|
||
---
|
||
|
||
## 0. 任务拆分原则
|
||
|
||
- 先把**协议、边界、脚手架**固定,再做运行时逻辑
|
||
- 先做**可启动、可连接**,再做**配对/认证**
|
||
- 先做**核心 happy path**,再做**失败路径和安全硬化**
|
||
- 先做**Server / Client 各自最小闭环**,再做联调
|
||
- 每个任务尽量满足:
|
||
- 范围明确
|
||
- 可以单独提交
|
||
- 有清晰验收标准
|
||
|
||
---
|
||
|
||
## Phase 0 — 仓库与规范对齐
|
||
|
||
### YNX-0001 统一仓库定位与术语
|
||
**目标**
|
||
- 统一文档中对 Yonexus、Yonexus.Server、Yonexus.Client、Yonexus.Protocol 的描述
|
||
- 明确这是“umbrella + 三个独立仓库/子模块”的模型
|
||
|
||
**子任务**
|
||
- 检查 `README.md`、`PLAN.md`、`FEAT.md`、`PROTOCOL.md` 术语是否一致
|
||
- 明确 `builtin`、`rule_identifier`、`identifier`、`secret`、`pairingCode` 等词汇定义
|
||
- 记录 v1 非目标,避免实现漂移
|
||
|
||
**验收标准**
|
||
- 核心文档不存在角色冲突或架构冲突描述
|
||
- 协议字段名称在文档中保持一致
|
||
|
||
---
|
||
|
||
### YNX-0002 定义 v1 实现边界
|
||
**目标**
|
||
- 把“必须做”和“以后再说”彻底分开
|
||
|
||
**子任务**
|
||
- 固化 v1 必做项:WebSocket、pairing、auth、heartbeat、rule dispatch、持久化
|
||
- 固化 v1 不做项:多服务器、离线消息队列、复杂规则匹配、管理 UI
|
||
- 明确心跳 ack 是否默认开启
|
||
- 明确断线重连采用指数退避还是固定退避
|
||
|
||
**验收标准**
|
||
- 有一份可执行的 v1 scope 列表
|
||
- 实现阶段不再反复讨论边界
|
||
|
||
---
|
||
|
||
## Phase 1 — 协议落地与共享契约
|
||
|
||
### YNX-0101 固化 builtin 协议信封与类型枚举
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 把 `PROTOCOL.md` 里的 builtin envelope 转成共享 TypeScript 类型
|
||
|
||
**子任务**
|
||
- 定义 `BuiltinEnvelope`
|
||
- 定义所有 builtin `type` 的联合类型
|
||
- 定义 payload 接口:`HelloPayload`、`PairRequestPayload`、`PairConfirmPayload`、`PairSuccessPayload`、`AuthRequestPayload`、`HeartbeatPayload` 等
|
||
- 统一 `timestamp` 使用 UTC unix seconds
|
||
|
||
**产出**
|
||
- `Yonexus.Protocol` 中的共享类型文件
|
||
|
||
**验收标准**
|
||
- Server / Client 都能直接复用类型
|
||
- 所有 builtin 消息都可被类型系统约束
|
||
|
||
**已完成内容**
|
||
- 已在 `Yonexus.Protocol/src/types.ts` 落地 `BuiltinEnvelope`、builtin `type` 联合类型、各类 payload 接口与 `BuiltinPayloadMap`
|
||
- 已增加 `Yonexus.Protocol/src/index.ts` 作为导出入口
|
||
- 已同步更新 `Yonexus.Protocol/README.md`,让共享类型入口不再停留在 planned 状态
|
||
|
||
---
|
||
|
||
### YNX-0102 实现协议编解码工具
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 提供统一的字符串协议解析与序列化能力
|
||
|
||
**子任务**
|
||
- 实现 `encodeBuiltin(envelope)`
|
||
- 实现 `decodeBuiltin(raw)`
|
||
- 实现 rule message 的首段分隔解析
|
||
- 确保 message content 中包含 `::` 时不会被错误切碎
|
||
- 为 malformed message 提供标准错误
|
||
|
||
**验收标准**
|
||
- `builtin::{json}` 可稳定双向转换
|
||
- `rule::content` 和 `rule::sender::content` 都能正确解析
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Protocol/src/codec.ts`
|
||
- 已实现 `encodeBuiltin` / `decodeBuiltin` 及类型安全的 envelope builders
|
||
- 已实现 `parseRuleMessage` / `parseRewrittenRuleMessage` / `encodeRuleMessage` / `encodeRewrittenRuleMessage`
|
||
- 已提供 `CodecError` 标准错误类及辅助函数 `isBuiltinMessage`
|
||
- 已更新 `Yonexus.Protocol/src/index.ts` 导出 codec 模块
|
||
|
||
---
|
||
|
||
### YNX-0103 定义协议错误码与错误对象
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 统一错误语义,避免 Server / Client 各自发明错误格式
|
||
|
||
**子任务**
|
||
- 定义协议错误码枚举
|
||
- 定义错误 envelope payload 结构
|
||
- 区分:配置错误、协议错误、认证错误、配对错误、运行时错误
|
||
|
||
**验收标准**
|
||
- 所有失败路径都能落到有限集合的错误码
|
||
- 文档与代码错误码一致
|
||
|
||
**已完成内容**
|
||
- 已在 `Yonexus.Protocol/src/types.ts` 固化 `ProtocolErrorCode` 与 `ErrorPayload`
|
||
- 已新增 `Yonexus.Protocol/src/errors.ts`,提供 `YonexusProtocolError`、错误分类映射、payload/envelope 转换辅助函数
|
||
- 已更新 `Yonexus.Protocol/src/index.ts` 导出错误模块,方便 Server / Client 统一复用
|
||
|
||
---
|
||
|
||
### YNX-0104 编写协议级测试样例
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 在实现运行时前,先锁定协议行为
|
||
|
||
**子任务**
|
||
- 为 hello / pair / auth / heartbeat / error 编写样例用例
|
||
- 为 malformed、缺字段、错误 rule、保留字冲突编写反例
|
||
- 为 `::` 分隔边界编写测试
|
||
|
||
**验收标准**
|
||
- 协议测试能独立运行
|
||
- 后续实现可直接拿这些样例做回归
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Protocol/tests/codec.test.ts`
|
||
- 已覆盖 `encodeBuiltin`/`decodeBuiltin`、`parseRuleMessage`/`encodeRuleMessage`、服务器重写消息解析/编码
|
||
- 已包含 malformed message、非法 rule identifier、保留字冲突等反例
|
||
- 已提供完整的 hello flow、rule message flow 示例
|
||
- 已配置 `package.json`、`tsconfig.json`、`vitest.config.ts` 测试基础设施
|
||
|
||
---
|
||
|
||
## Phase 2 — Server 插件脚手架
|
||
|
||
### YNX-0201 创建 Yonexus.Server 最小插件骨架
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 让 Server 插件可被 OpenClaw 加载
|
||
|
||
**已完成内容**
|
||
- 已补齐 `plugin/`、`servers/`、`skills/`、`scripts/` 目录骨架
|
||
- 已创建 `package.json`、`tsconfig.json`
|
||
- 已写入 `plugin/openclaw.plugin.json`
|
||
- 已补齐 wiring-only `plugin/index.ts`
|
||
- 已补齐最小 `scripts/install.mjs`
|
||
|
||
**验收标准**
|
||
- 插件能被识别
|
||
- 启动时至少能加载但不报致命错误
|
||
|
||
---
|
||
|
||
### YNX-0202 定义 Yonexus.Server 配置 schema
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 让 Server 配置在启动前就能被校验
|
||
|
||
**子任务**
|
||
- 校验 `followerIdentifiers`
|
||
- 校验 `notifyBotToken`
|
||
- 校验 `adminUserId`
|
||
- 校验 `listenPort`
|
||
- 校验 `listenHost` / `publicWsUrl` 可选字段
|
||
- 启动失败时返回明确错误
|
||
|
||
**验收标准**
|
||
- 缺字段和非法字段会 fail fast
|
||
- 错误信息足够定位问题
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/core/config.ts`
|
||
- 已实现 `validateYonexusServerConfig()` 与 `YonexusServerConfigError`
|
||
- 已覆盖 `followerIdentifiers`、`notifyBotToken`、`adminUserId`、`listenPort`、`listenHost`、`publicWsUrl` 的基础约束与默认值处理
|
||
- 已从 `plugin/index.ts` 导出配置类型与校验入口,方便后续 lifecycle wiring 复用
|
||
|
||
---
|
||
|
||
### YNX-0203 实现 Server 生命周期 wiring
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 在 gateway 启动时初始化 Server 内部组件
|
||
|
||
**子任务**
|
||
- 初始化配置
|
||
- 初始化 registry
|
||
- 初始化持久化层
|
||
- 初始化 rule registry
|
||
- 注册 shutdown 清理逻辑
|
||
|
||
**验收标准**
|
||
- 启停流程完整
|
||
- 不会留下悬挂 timer / socket
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/core/runtime.ts`
|
||
- 已实现 `YonexusServerRuntime`,负责加载持久化记录、补齐 allowlist 默认 record、驱动 transport start/stop 与 shutdown 前持久化
|
||
- 已把连接会话映射进 `ServerRegistry.sessions`,并在断开时回收 session / 更新离线状态
|
||
- 已从 `Yonexus.Server/plugin/index.ts` 导出 runtime 入口,便于后续接入 OpenClaw lifecycle wiring
|
||
|
||
---
|
||
|
||
## Phase 3 — Client 插件脚手架
|
||
|
||
### YNX-0301 创建 Yonexus.Client 最小插件骨架
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 让 Client 插件可被 OpenClaw 加载
|
||
|
||
**已完成内容**
|
||
- 已补齐 `plugin/`、`servers/`、`skills/`、`scripts/` 目录骨架
|
||
- 已创建 `package.json`、`tsconfig.json`
|
||
- 已写入 `plugin/openclaw.plugin.json`
|
||
- 已补齐 wiring-only `plugin/index.ts`
|
||
- 已补齐最小 `scripts/install.mjs`
|
||
|
||
**验收标准**
|
||
- 插件能被识别并加载
|
||
|
||
---
|
||
|
||
### YNX-0302 定义 Yonexus.Client 配置 schema
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 保证 Client 配置可启动前校验
|
||
|
||
**子任务**
|
||
- 校验 `mainHost`
|
||
- 校验 `identifier`
|
||
- 校验 `notifyBotToken`
|
||
- 校验 `adminUserId`
|
||
- 规范 `mainHost` 是否允许裸 `host:port`
|
||
|
||
**验收标准**
|
||
- 配置错误可在启动时直接发现
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Client/plugin/core/config.ts`
|
||
- 已实现 `validateYonexusClientConfig()` 与 `YonexusClientConfigError`
|
||
- 已覆盖 `mainHost`、`identifier`、`notifyBotToken`、`adminUserId` 的必填校验,并限定 `mainHost` 为 `ws://` / `wss://`
|
||
- 已从 `plugin/index.ts` 导出配置类型与校验入口,方便后续 lifecycle wiring 直接接入
|
||
|
||
---
|
||
|
||
### YNX-0303 实现 Client 生命周期 wiring
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 在 gateway 启动时初始化 Client 运行时
|
||
|
||
**子任务**
|
||
- 加载本地状态
|
||
- 初始化连接管理器
|
||
- 初始化规则注册器
|
||
- 注册 shutdown 清理逻辑
|
||
|
||
**验收标准**
|
||
- Client 可启动并在未连接状态下稳定运行
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Client/plugin/core/runtime.ts`
|
||
- 已实现 `YonexusClientRuntime`,负责加载本地 state、驱动 transport connect/disconnect,并维护最小 phase 状态机
|
||
- 已将 lifecycle 状态从 `plugin/index.ts` 导出,便于后续挂接 gateway startup/shutdown
|
||
- 已把 hello 发送时机放到 transport 连接成功后统一触发,避免后续 handshake wiring 分散在多个入口
|
||
|
||
---
|
||
|
||
## Phase 4 — 持久化与状态模型
|
||
|
||
### YNX-0401 定义 Server 持久化记录结构
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 把 `PLAN.md` 中的 `ClientRecord` 落到代码
|
||
|
||
**子任务**
|
||
- 定义 paired/unpaired/revoked/pending 状态
|
||
- 定义 heartbeat/liveness 字段
|
||
- 定义 pairing 通知字段
|
||
- 定义 recent nonce / recent attempts 窗口结构
|
||
- 定义 `createdAt` / `updatedAt`
|
||
|
||
**验收标准**
|
||
- 持久化结构足以支撑 pairing/auth/heartbeat
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/core/persistence.ts`
|
||
- 已实现 `ClientRecord`、`ClientSession`、`ServerRegistry` 接口
|
||
- 已实现 `SerializedClientRecord`、`ServerPersistenceData` 持久化结构
|
||
- 已提供 `createClientRecord`、`serializeClientRecord`、`deserializeClientRecord` 工厂函数
|
||
- 已提供 `isPairable`、`hasPendingPairing`、`isPairingExpired`、`canAuthenticate` 状态检查函数
|
||
- 已更新 `Yonexus.Server/plugin/index.ts` 导出 persistence 模块
|
||
|
||
---
|
||
|
||
### YNX-0402 实现 Server 状态存储
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 让信任状态在重启后仍可恢复
|
||
|
||
**子任务**
|
||
- 选择 JSON 文件或等价轻量持久化形式
|
||
- 实现加载、保存、原子写入
|
||
- 区分持久数据与内存态数据
|
||
- 明确 restart 后是否清空 rolling windows
|
||
|
||
**验收标准**
|
||
- 重启后 paired client 不丢失
|
||
- 损坏文件时有可恢复行为
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/core/store.ts`,采用 JSON 文件作为 v1 持久化载体
|
||
- 已实现 `loadServerStore()` / `saveServerStore()` 与 `createYonexusServerStore()`
|
||
- 已使用 `*.tmp` + rename 的原子写入策略
|
||
- 已在加载阶段校验文件结构,并在损坏/版本不匹配时抛出明确 corruption error
|
||
- 已明确 rolling security windows 通过 `deserializeClientRecord()` 在重启后清空
|
||
|
||
---
|
||
|
||
### YNX-0403 实现 Client 本地信任材料存储
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 持久化 Client 的 `identifier`、私钥、secret
|
||
|
||
**子任务**
|
||
- 定义本地 state 文件结构
|
||
- 实现加载 / 初始化 / 保存
|
||
- 缺失文件时自动初始化最小状态
|
||
- 标记敏感字段
|
||
|
||
**验收标准**
|
||
- Client 重启后可恢复身份与 secret
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Client/plugin/core/state.ts`
|
||
- 已定义 `YonexusClientState` / `YonexusClientStateFile`,覆盖 `identifier`、`privateKey`、`publicKey`、`secret` 与关键时间戳
|
||
- 已实现 `loadYonexusClientState()` / `saveYonexusClientState()` / `createYonexusClientStateStore()`
|
||
- 已支持 state 文件缺失时自动创建最小初始状态
|
||
- 已补充 `hasClientSecret()` 与 `hasClientKeyPair()`,方便后续 handshake wiring 判断本地信任材料是否齐备
|
||
|
||
---
|
||
|
||
## Phase 5 — Transport 最小闭环
|
||
|
||
### YNX-0501 实现 Server WebSocket 启动与连接接入
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- Server 能监听并接受连接
|
||
|
||
**子任务**
|
||
- 启动 WebSocket server
|
||
- 处理 connect / message / close / error
|
||
- 记录连接与 identifier 绑定前的临时会话
|
||
|
||
**验收标准**
|
||
- 可看到客户端连接进入
|
||
- 无协议时也不会崩
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/core/transport.ts`
|
||
- 已实现 `YonexusServerTransport`,支持 start/stop、send/broadcast、连接管理
|
||
- 已实现临时连接追踪、已认证连接管理、单 identifier 单连接策略
|
||
- 已更新 `plugin/index.ts` 导出 transport 模块
|
||
|
||
---
|
||
|
||
### YNX-0502 实现 Client WebSocket 连接器
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- Client 能主动连到 Server
|
||
|
||
**子任务**
|
||
- 建立 outbound 连接
|
||
- 处理 open / message / close / error
|
||
- 提供连接状态机
|
||
|
||
**验收标准**
|
||
- Client 能连上可用的 Server
|
||
- Server 不可用时不会死循环刷日志
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Client/plugin/core/transport.ts`
|
||
- 已实现 `YonexusClientTransport`,支持 connect/disconnect/send
|
||
- 已实现指数退避重连策略(max 10 次,1s~30s 退避)
|
||
- 已实现心跳 timer 基础设施
|
||
- 已更新 `plugin/index.ts` 导出 transport 模块
|
||
|
||
---
|
||
|
||
### YNX-0503 实现 hello / hello_ack
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 完成连接后的第一段协议握手
|
||
|
||
**子任务**
|
||
- Client 连接后发送 `hello`
|
||
- Server 验证 `identifier`、协议版本、payload 形状
|
||
- Server 返回 `hello_ack`
|
||
- 根据状态决定 `nextAction`
|
||
|
||
**验收标准**
|
||
- 未配对客户端收到 `pair_required`
|
||
- 已配对客户端收到 `auth_required`
|
||
- 非 allowlist 客户端被拒绝
|
||
|
||
**已完成内容**
|
||
- Client runtime 已在连接建立后发送 `hello`,内容包含 `identifier`、协议版本、`hasSecret`、`hasKeyPair` 与可选 `publicKey`
|
||
- Server runtime 已接入 builtin `hello` 处理,校验 allowlist 与协议版本,并返回 `hello_ack`
|
||
- `hello_ack.nextAction` 已按 record 状态区分为 `pair_required` / `waiting_pair_confirm` / `auth_required`
|
||
- 对非法 identifier 与不支持的协议版本已返回协议错误,并在版本不匹配时主动关闭连接
|
||
|
||
**进展说明**
|
||
- 本次只完成最小握手闭环;后续 `auth_request`、`pair_request` 等具体动作仍由 Phase 6/7 继续补齐
|
||
|
||
---
|
||
|
||
### YNX-0504 实现基础重连策略
|
||
**目标**
|
||
- Client 断线后可恢复连接
|
||
|
||
**子任务**
|
||
- 设计退避策略
|
||
- 避免并发多次重连
|
||
- 在成功连接后重置退避计数
|
||
|
||
**验收标准**
|
||
- 断线可自动恢复
|
||
- 不会形成高频重连风暴
|
||
|
||
---
|
||
|
||
## Phase 6 — Pairing 主流程
|
||
|
||
### YNX-0601 实现 Client 首次密钥生成
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- Client 首次运行自动生成本地公私钥
|
||
|
||
**子任务**
|
||
- 选定签名算法(建议 Ed25519)
|
||
- 生成 keypair
|
||
- 保存私钥
|
||
- 导出公钥供握手使用
|
||
|
||
**验收标准**
|
||
- 首次启动可生成并持久化 keypair
|
||
- 重启不会重复生成
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Client/plugin/crypto/keypair.ts`,使用 Ed25519 生成并导出 PEM keypair
|
||
- 已在 `Yonexus.Client/plugin/core/state.ts` 增加 `ensureClientKeyPair()`,首次启动自动生成并持久化 keypair
|
||
- Client runtime 启动时自动确保 keypair 存在
|
||
|
||
---
|
||
|
||
### YNX-0602 实现 Server pairing request 创建
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- Server 可为待配对客户端创建 pairing 会话
|
||
|
||
**子任务**
|
||
- 生成 pairing code
|
||
- 生成 expiresAt / ttl
|
||
- 将状态写入 registry
|
||
- 更新 pairing 状态为 pending
|
||
|
||
**验收标准**
|
||
- 每次 pairing 会话有可验证的过期时间
|
||
- pairing code 不会通过 Yonexus WS 下发
|
||
|
||
**已完成内容**
|
||
- 已新增 `Yonexus.Server/plugin/services/pairing.ts`,封装 pairing code/TTL/状态写入
|
||
- Server runtime 在 `pair_required` 时创建 pending pairing 记录并持久化
|
||
|
||
---
|
||
|
||
### YNX-0603 实现 Discord DM 配对通知
|
||
**目标**
|
||
- Server 通过 `notifyBotToken` 向 `adminUserId` 发送 pairing code
|
||
|
||
**子任务**
|
||
- 封装 Discord DM 发送逻辑
|
||
- DM 内容包含 identifier、pairingCode、expiresAt/TTL
|
||
- 处理发送失败
|
||
- 记录 pairing notification metadata
|
||
|
||
**验收标准**
|
||
- 通知成功时 Client 才能进入可确认状态
|
||
- 通知失败时不会继续配对成功路径
|
||
|
||
**进展说明**
|
||
- 已新增 `Yonexus.Server/plugin/notifications/discord.ts` 作为通知服务骨架
|
||
- 当前为日志输出 stub,仍需接入真实 Discord DM 发送逻辑
|
||
- runtime 已在 pairing 创建后调用通知服务并记录 sent/failed 元数据
|
||
|
||
---
|
||
|
||
### YNX-0604 实现 pair_request / pair_confirm / pair_success
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 打通完整配对流程
|
||
|
||
**子任务**
|
||
- Server 下发不含 code 的 `pair_request`
|
||
- Client 接收并进入 pairing pending
|
||
- Client 提交 `pair_confirm`
|
||
- Server 校验 code 和 expiry
|
||
- 成功后生成 secret
|
||
- Server 返回 `pair_success`
|
||
- Client 保存 secret
|
||
|
||
**验收标准**
|
||
- 正确 code 可完成配对
|
||
- 错误 code / 过期 code 会失败
|
||
|
||
**已完成内容**
|
||
- Server runtime 已在 `hello_ack` 后发送 `pair_request`,并复用已有 pending pairing 的 TTL/状态元数据
|
||
- Client runtime 已接收 `pair_request`,记录 pending pairing 元数据并切换到 `waiting_pair_confirm`
|
||
- Client runtime 已新增 `submitPairingCode()`,用于发送 `pair_confirm`
|
||
- Server runtime 已实现 `pair_confirm` 校验、`pair_success` 下发,并在成功后把 secret/publicKey 持久化到服务端记录
|
||
- Client runtime 已在收到 `pair_success` 后保存 secret/pairedAt 到本地 state
|
||
|
||
---
|
||
|
||
### YNX-0605 实现配对失败路径
|
||
**状态**
|
||
- [x] 已完成(2026-04-08)
|
||
|
||
**目标**
|
||
- 补齐 pairing 相关失败逻辑
|
||
|
||
**子任务**
|
||
- `invalid_code`
|
||
- `expired`
|
||
- `identifier_not_allowed`
|
||
- `admin_notification_failed`
|
||
- `internal_error`
|
||
- 配对失败后的状态恢复策略
|
||
|
||
**验收标准**
|
||
- 失败后不会留下脏状态导致后续无法重试
|
||
|
||
**已完成内容**
|
||
- Server runtime 已为 `pair_confirm` 补齐 `identifier_not_allowed`、`invalid_code`、`expired`、`internal_error` 的 `pair_failed` 返回
|
||
- Server runtime 已在配对通知失败时下发 `pair_failed(admin_notification_failed)` 并清理 pending pairing 状态,避免留下脏状态
|
||
- Client runtime 已记录最近一次 pairing failure,并根据 `expired` / `admin_notification_failed` 自动回退到 `pair_required`
|
||
- 其他失败原因会保留 `waiting_pair_confirm`,允许客户端在同一 pairing 会话内重试输入 code
|
||
|
||
---
|
||
|
||
## Phase 7 — Authentication 主流程
|
||
|
||
### YNX-0701 固化 proof 构造与签名规范
|
||
**目标**
|
||
- 明确签名输入,避免 Server / Client 不一致
|
||
|
||
**子任务**
|
||
- 决定 canonical serialization 方案
|
||
- 明确签名字段:secret、nonce、timestamp
|
||
- 定义签名编码格式(如 base64)
|
||
|
||
**验收标准**
|
||
- 同一输入在 Client 与 Server 上验证一致
|
||
|
||
---
|
||
|
||
### YNX-0702 实现 Client auth_request
|
||
**目标**
|
||
- Client 能基于本地 secret 与私钥发起认证
|
||
|
||
**子任务**
|
||
- 生成 24 字符 nonce
|
||
- 生成 proofTimestamp
|
||
- 构造签名
|
||
- 发送 `auth_request`
|
||
|
||
**验收标准**
|
||
- 报文字段完整
|
||
- nonce 格式符合协议要求
|
||
|
||
---
|
||
|
||
### YNX-0703 实现 Server 认证校验
|
||
**目标**
|
||
- Server 能验证 auth_request 真伪
|
||
|
||
**子任务**
|
||
- 校验 identifier allowlist
|
||
- 校验 paired 状态
|
||
- 校验 publicKey 匹配
|
||
- 校验 signature
|
||
- 校验 secret
|
||
- 校验 timestamp 漂移
|
||
- 校验 nonce 重放
|
||
- 校验 attempts 频率
|
||
|
||
**验收标准**
|
||
- 正确认证返回 `auth_success`
|
||
- 各类失败返回对应 `auth_failed`
|
||
|
||
---
|
||
|
||
### YNX-0704 实现 re_pair_required 机制
|
||
**目标**
|
||
- 在不安全条件下强制重新配对
|
||
|
||
**子任务**
|
||
- 检测 nonce collision
|
||
- 检测 `>10 attempts / 10s`
|
||
- 失效旧 secret 或标记 trust revoked
|
||
- 返回 `re_pair_required`
|
||
- Client 收到后切回 pairing_required
|
||
|
||
**验收标准**
|
||
- 不安全状态下不会继续接受旧信任材料
|
||
|
||
---
|
||
|
||
## Phase 8 — Heartbeat 与在线状态
|
||
|
||
### YNX-0801 实现 Client heartbeat loop
|
||
**目标**
|
||
- Client 在认证后按周期发心跳
|
||
|
||
**子任务**
|
||
- 认证成功后启动 heartbeat timer
|
||
- 断线或未认证时停止 timer
|
||
- 发送 `heartbeat`
|
||
|
||
**验收标准**
|
||
- 默认每 5 分钟发送一次
|
||
- 状态切换时 timer 无泄漏
|
||
|
||
---
|
||
|
||
### YNX-0802 实现 Server heartbeat 接收与记录
|
||
**目标**
|
||
- Server 能更新客户端最近存活时间
|
||
|
||
**子任务**
|
||
- 接收 heartbeat
|
||
- 校验来源已认证
|
||
- 更新 `lastHeartbeatAt`
|
||
- 可选返回 `heartbeat_ack`
|
||
|
||
**验收标准**
|
||
- 收到心跳后客户端状态可维持在线
|
||
|
||
---
|
||
|
||
### YNX-0803 实现 Server liveness sweep
|
||
**目标**
|
||
- Server 能周期性评估 online / unstable / offline
|
||
|
||
**子任务**
|
||
- 增加 30~60s sweep timer
|
||
- 7 分钟无心跳标记 unstable
|
||
- 11 分钟无心跳标记 offline
|
||
- offline 时发送 `disconnect_notice` 并断开连接
|
||
|
||
**验收标准**
|
||
- 状态转移符合文档定义
|
||
|
||
---
|
||
|
||
## Phase 9 — 规则消息与 API
|
||
|
||
### YNX-0901 实现 Client rule registry
|
||
**目标**
|
||
- Client 侧支持应用层规则分发
|
||
|
||
**子任务**
|
||
- 实现 `registerRule(rule, processor)`
|
||
- 禁止 `builtin`
|
||
- 默认禁止重复注册
|
||
- 按 exact match 分发
|
||
|
||
**验收标准**
|
||
- 命中规则时正确调用处理器
|
||
- 非法注册被拒绝
|
||
|
||
---
|
||
|
||
### YNX-0902 实现 Server rule registry
|
||
**目标**
|
||
- Server 侧支持应用层规则分发
|
||
|
||
**子任务**
|
||
- 实现 `registerRule(rule, processor)`
|
||
- 禁止 `builtin`
|
||
- 默认禁止重复注册
|
||
- 按 exact match 分发
|
||
|
||
**验收标准**
|
||
- 规则注册与调用行为一致
|
||
|
||
---
|
||
|
||
### YNX-0903 实现 `sendMessageToServer(message)`
|
||
**目标**
|
||
- 暴露 Client 到 Server 的发送 API
|
||
|
||
**子任务**
|
||
- 校验连接/认证状态
|
||
- 发送 `${rule_identifier}::${message_content}`
|
||
- 未连接时返回明确错误
|
||
|
||
**验收标准**
|
||
- 上层插件可直接调用
|
||
|
||
---
|
||
|
||
### YNX-0904 实现 `sendMessageToClient(identifier, message)`
|
||
**目标**
|
||
- 暴露 Server 到指定 Client 的发送 API
|
||
|
||
**子任务**
|
||
- 校验目标 client 已知且在线
|
||
- 发送 `${rule_identifier}::${message_content}`
|
||
- 离线时返回明确错误
|
||
|
||
**验收标准**
|
||
- 上层插件可向指定客户端投递消息
|
||
|
||
---
|
||
|
||
### YNX-0905 实现 Server 入站消息重写
|
||
**目标**
|
||
- 把客户端来的消息重写成带 sender 标识的形式
|
||
|
||
**子任务**
|
||
- 解析 `${rule_identifier}::${message_content}`
|
||
- 重写为 `${rule_identifier}::${sender_identifier}::${message_content}`
|
||
- 再进入 rule dispatch
|
||
|
||
**验收标准**
|
||
- Server 侧处理器能可靠识别消息来源
|
||
|
||
---
|
||
|
||
## Phase 10 — 安全与鲁棒性
|
||
|
||
### YNX-1001 实现敏感信息脱敏日志
|
||
**目标**
|
||
- 避免 secret、私钥、proof 原文进入日志
|
||
|
||
**子任务**
|
||
- 定义 redaction 工具
|
||
- 覆盖 pairing、auth、error 日志路径
|
||
- 对外只保留必要上下文
|
||
|
||
**验收标准**
|
||
- 关键敏感值不会明文打印
|
||
|
||
---
|
||
|
||
### YNX-1002 实现 malformed / unsupported / unauthorized 防御
|
||
**目标**
|
||
- 所有非法输入都能被可控拒绝
|
||
|
||
**子任务**
|
||
- malformed json
|
||
- 缺字段 payload
|
||
- unsupported protocol version
|
||
- unauthorized identifier
|
||
- 非法 builtin type
|
||
|
||
**验收标准**
|
||
- 错误不会导致进程崩溃
|
||
- 客户端能收到明确错误反馈或断开
|
||
|
||
---
|
||
|
||
### YNX-1003 实现单 identifier 单活跃连接策略
|
||
**目标**
|
||
- 同一 client identifier 只允许一个活跃认证连接
|
||
|
||
**子任务**
|
||
- 定义旧连接替换策略
|
||
- 新连接成功认证后踢掉旧连接
|
||
- 避免竞态导致双在线
|
||
|
||
**验收标准**
|
||
- 任意时刻同一 identifier 只有一个有效 session
|
||
|
||
---
|
||
|
||
### YNX-1004 实现重启恢复策略
|
||
**目标**
|
||
- 重启后行为可预期且文档一致
|
||
|
||
**子任务**
|
||
- 恢复 durable trust records
|
||
- 清理或重建 rolling windows
|
||
- 明确 pending pairing 如何恢复
|
||
- 明确 active connection 状态如何重建
|
||
|
||
**验收标准**
|
||
- 重启后的认证/配对行为稳定可解释
|
||
|
||
---
|
||
|
||
## Phase 11 — 测试与联调
|
||
|
||
### YNX-1101 编写协议单元测试
|
||
**目标**
|
||
- 覆盖编解码、字段校验、错误码
|
||
|
||
### YNX-1102 编写 Server 单元测试
|
||
**目标**
|
||
- 覆盖 registry、pairing、auth、heartbeat sweep
|
||
|
||
### YNX-1103 编写 Client 单元测试
|
||
**目标**
|
||
- 覆盖状态机、keypair、auth 构造、heartbeat timer
|
||
|
||
### YNX-1104 编写 Server-Client 集成测试
|
||
**目标**
|
||
- 覆盖首次配对、正常重连、认证失败、心跳超时、re-pair
|
||
|
||
### YNX-1105 编写失败路径测试矩阵
|
||
**目标**
|
||
- 系统性覆盖 pairing/auth 失败路径
|
||
|
||
**重点场景**
|
||
- pairing code 错误
|
||
- pairing 过期
|
||
- DM 发送失败
|
||
- stale timestamp
|
||
- future timestamp
|
||
- nonce collision
|
||
- handshake rate limit
|
||
- unknown identifier
|
||
- duplicate connection
|
||
|
||
**验收标准**
|
||
- 核心安全路径都有自动化测试
|
||
|
||
---
|
||
|
||
## Phase 12 — 文档与交付
|
||
|
||
### YNX-1201 补齐 Server README
|
||
**目标**
|
||
- Server 仓库可独立被安装与使用
|
||
|
||
### YNX-1202 补齐 Client README
|
||
**目标**
|
||
- Client 仓库可独立被安装与使用
|
||
|
||
### YNX-1203 输出部署文档
|
||
**目标**
|
||
- 写清楚单主多从部署方式、配置示例、配对流程
|
||
|
||
### YNX-1204 输出运维排障文档
|
||
**目标**
|
||
- 写清楚常见报错、状态含义、恢复步骤
|
||
|
||
### YNX-1205 输出协议测试与验收清单
|
||
**目标**
|
||
- 让后续改动有统一回归基线
|
||
|
||
---
|
||
|
||
## 推荐执行顺序(最小闭环)
|
||
|
||
### Milestone A — 能启动
|
||
- YNX-0101
|
||
- YNX-0102
|
||
- YNX-0201
|
||
- YNX-0202
|
||
- YNX-0301
|
||
- YNX-0302
|
||
- YNX-0401
|
||
- YNX-0402
|
||
- YNX-0403
|
||
|
||
### Milestone B — 能连接
|
||
- YNX-0203
|
||
- YNX-0303
|
||
- YNX-0501
|
||
- YNX-0502
|
||
- YNX-0503
|
||
- YNX-0504
|
||
|
||
### Milestone C — 能配对认证
|
||
- YNX-0601
|
||
- YNX-0602
|
||
- YNX-0603
|
||
- YNX-0604
|
||
- YNX-0605
|
||
- YNX-0701
|
||
- YNX-0702
|
||
- YNX-0703
|
||
- YNX-0704
|
||
|
||
### Milestone D — 能稳定通信
|
||
- YNX-0801
|
||
- YNX-0802
|
||
- YNX-0803
|
||
- YNX-0901
|
||
- YNX-0902
|
||
- YNX-0903
|
||
- YNX-0904
|
||
- YNX-0905
|
||
|
||
### Milestone E — 能交付
|
||
- YNX-1001
|
||
- YNX-1002
|
||
- YNX-1003
|
||
- YNX-1004
|
||
- YNX-1101
|
||
- YNX-1102
|
||
- YNX-1103
|
||
- YNX-1104
|
||
- YNX-1105
|
||
- YNX-1201
|
||
- YNX-1202
|
||
- YNX-1203
|
||
- YNX-1204
|
||
- YNX-1205
|
||
|
||
---
|
||
|
||
## 可直接开工的首批任务
|
||
|
||
如果要我给出“今天就能开始做”的第一批,我建议是:
|
||
|
||
1. YNX-0101 固化共享协议类型
|
||
2. YNX-0102 实现协议编解码工具
|
||
3. YNX-0201 创建 Yonexus.Server 插件骨架
|
||
4. YNX-0301 创建 Yonexus.Client 插件骨架
|
||
5. YNX-0401 定义 Server / Client 状态模型
|
||
6. YNX-0503 实现 hello / hello_ack 最小握手
|
||
|
||
这样最快能拿到一个“能启动、能连接、能判断下一步动作”的基础闭环。
|