Files
Yonexus/TASKLIST.md

1345 lines
46 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.
# Yonexus — TASKLIST
基于 `FEAT.md``PLAN.md``PROTOCOL.md``README.md` 整理。
目标:把 Yonexus 从“规划完成、实现未开始”的状态,拆成可逐项交付、可验收、尽量低耦合的小任务列表。
---
## 0. 任务拆分原则
- 先把**协议、边界、脚手架**固定,再做运行时逻辑
- 先做**可启动、可连接**,再做**配对/认证**
- 先做**核心 happy path**,再做**失败路径和安全硬化**
- 先做**Server / Client 各自最小闭环**,再做联调
- 每个任务尽量满足:
- 范围明确
- 可以单独提交
- 有清晰验收标准
---
## Phase 0 — 仓库与规范对齐
### YNX-0001 统一仓库定位与术语
**状态**
- [x] 已完成2026-04-09
**目标**
- 统一文档中对 Yonexus、Yonexus.Server、Yonexus.Client、Yonexus.Protocol 的描述
- 明确这是“umbrella + 三个独立仓库/子模块”的模型
**子任务**
- 检查 `README.md``PLAN.md``FEAT.md``PROTOCOL.md` 术语是否一致
- 明确 `builtin``rule_identifier``identifier``secret``pairingCode` 等词汇定义
- 记录 v1 非目标,避免实现漂移
**验收标准**
- 核心文档不存在角色冲突或架构冲突描述
- 协议字段名称在文档中保持一致
**已完成内容**
- 已在 `README.md` 新增 Shared Terminology 区块,统一 umbrella repo 对核心术语的定义
- 已在 `PLAN.md` 新增 `Shared Terminology Baseline`,明确这些字段名为跨仓库规范用语
- 已在 `FEAT.md``PROTOCOL.md` 同步补齐 canonical terminology避免后续实现和文档再出现同义词漂移
---
### YNX-0002 定义 v1 实现边界
**状态**
- [x] 已完成2026-04-09
**目标**
- 把“必须做”和“以后再说”彻底分开
**子任务**
- 固化 v1 必做项WebSocket、pairing、auth、heartbeat、rule dispatch、持久化
- 固化 v1 不做项:多服务器、离线消息队列、复杂规则匹配、管理 UI
- 明确心跳 ack 是否默认开启
- 明确断线重连采用指数退避还是固定退避
**验收标准**
- 有一份可执行的 v1 scope 列表
- 实现阶段不再反复讨论边界
**已完成内容**
- 已在 `README.md` 增加 `v1 Scope Boundaries`,把 in-scope / out-of-scope 一次写清
- 已在 `PLAN.md` 将若干开放问题下沉为已锁定的 v1 决策Ed25519、完整 `mainHost` URL、`heartbeat_ack` optional、指数退避、exact-match rule、离线发送立即失败
- 已在 `FEAT.md``PROTOCOL.md` 同步这些边界,使功能清单与协议文档不再反复摇摆
---
## 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 实现基础重连策略
**状态**
- [x] 已完成2026-04-08
**目标**
- Client 断线后可恢复连接
**子任务**
- 设计退避策略
- 避免并发多次重连
- 在成功连接后重置退避计数
**验收标准**
- 断线可自动恢复
- 不会形成高频重连风暴
**已完成内容**
- 已将 Client transport 重连逻辑改为覆盖所有非主动异常断线,而不再仅限“已认证后掉线”场景
- 已增加 `shouldReconnect` 标志,确保手动 `disconnect()` 不会误触发自动重连
- 已在每次 `connect()` 前清理旧的 reconnect timer避免并发重连尝试叠加
- 已在成功连接后移除首个 `error` 监听并重置退避计数,避免首次建连阶段的错误监听残留
---
## 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 配对通知
**状态**
- [x] 已完成2026-04-09
**目标**
- Server 通过 `notifyBotToken``adminUserId` 发送 pairing code
**子任务**
- 封装 Discord DM 发送逻辑
- DM 内容包含 identifier、pairingCode、expiresAt/TTL
- 处理发送失败
- 记录 pairing notification metadata
**验收标准**
- 通知成功时 Client 才能进入可确认状态
- 通知失败时不会继续配对成功路径
**已完成内容**
- 已将 `Yonexus.Server/plugin/notifications/discord.ts` 从 stub 升级为基于 Discord REST API 的真实 DM 发送实现
- 已实现两段式调用:先创建/获取 DM channel再向该 channel 发送 pairing message
- 已保留 `formatPairingMessage()` 与 mock service便于测试与本地替身注入
- 已在通知层补齐配置缺失、HTTP 非 2xx、返回 payload 缺少 channel id 等失败处理,失败时返回 `false` 让 runtime 落到 `admin_notification_failed`
- 已新增 `Yonexus.Server/tests/notifications.test.ts`覆盖消息格式、成功发送、DM channel 创建失败、配置缺失四类场景
---
### 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 构造与签名规范
**状态**
- [x] 已完成2026-04-08
**目标**
- 明确签名输入,避免 Server / Client 不一致
**子任务**
- 决定 canonical serialization 方案
- 明确签名字段secret、nonce、timestamp
- 定义签名编码格式(如 base64
**验收标准**
- 同一输入在 Client 与 Server 上验证一致
**已完成内容**
- 已新增 `Yonexus.Protocol/src/auth.ts`固化认证共享常量nonce 长度、时间漂移窗口、attempt window、recent nonce window
- 已实现 `createAuthRequestSigningInput()` / `extractAuthRequestSigningInput()`,统一以稳定 JSON 序列化 `{ secret, nonce, timestamp }` 作为签名输入
- 已补充 `isValidAuthNonce()``isTimestampFresh()`,把 nonce 与时间窗口校验规则从文档落到共享代码
- 已从 `Yonexus.Protocol/src/index.ts` 导出认证辅助模块,供 Client / Server 复用
---
### YNX-0702 实现 Client auth_request
**状态**
- [x] 已完成2026-04-08
**目标**
- Client 能基于本地 secret 与私钥发起认证
**子任务**
- 生成 24 字符 nonce
- 生成 proofTimestamp
- 构造签名
- 发送 `auth_request`
**验收标准**
- 报文字段完整
- nonce 格式符合协议要求
**已完成内容**
- Client runtime 已在收到 `hello_ack(auth_required)``pair_success` 后自动发起 `auth_request`
- 已复用本地 `secret` + Ed25519 私钥生成签名,并发送 `identifier` / `nonce` / `proofTimestamp` / `signature` / `publicKey`
- 已把 transport 状态补齐为 `authenticating -> authenticated`,并在 `auth_success` 后落盘 `authenticatedAt`
- 已处理 `auth_failed` / `re_pair_required` 的最小状态回退逻辑
---
### YNX-0703 实现 Server 认证校验
**状态**
- [x] 已完成2026-04-08
**目标**
- Server 能验证 auth_request 真伪
**子任务**
- 校验 identifier allowlist
- 校验 paired 状态
- 校验 publicKey 匹配
- 校验 signature
- 校验 secret
- 校验 timestamp 漂移
- 校验 nonce 重放
- 校验 attempts 频率
**验收标准**
- 正确认证返回 `auth_success`
- 各类失败返回对应 `auth_failed`
**已完成内容**
- Server runtime 已接入 `auth_request` builtin 处理并校验 allowlist / paired 状态 / publicKey 一致性
- 已复用共享签名输入规范与 Ed25519 验签逻辑,验证客户端签名
- 已实现 timestamp freshness、nonce 格式、recent nonce collision、10s attempt window 的最小校验
- 正常认证会更新 `lastAuthenticatedAt` / `lastHeartbeatAt` / liveness 状态,并返回 `auth_success`
- 遇到 nonce collision 或 rate limit 时会触发 `re_pair_required`,清理旧 secret 与安全窗口
---
### YNX-0704 实现 re_pair_required 机制
**状态**
- [x] 已完成2026-04-08
**目标**
- 在不安全条件下强制重新配对
**子任务**
- 检测 nonce collision
- 检测 `>10 attempts / 10s`
- 失效旧 secret 或标记 trust revoked
- 返回 `re_pair_required`
- Client 收到后切回 pairing_required
**验收标准**
- 不安全状态下不会继续接受旧信任材料
**已完成内容**
- Server 端在 nonce collision / rate limit 时触发 `re_pair_required` 并清空 secret 与安全窗口
- Client 收到 `re_pair_required``auth_failed(re_pair_required)` 后清除本地 secret 并回退到 `pair_required`
---
## Phase 8 — Heartbeat 与在线状态
### YNX-0801 实现 Client heartbeat loop
**状态**
- [x] 已完成2026-04-08
**目标**
- Client 在认证后按周期发心跳
**子任务**
- 认证成功后启动 heartbeat timer
- 断线或未认证时停止 timer
- 发送 `heartbeat`
**验收标准**
- 默认每 5 分钟发送一次
- 状态切换时 timer 无泄漏
**已完成内容**
- Client transport 在认证后启动 5 分钟 heartbeat 定时器
- Runtime 处理 heartbeat tick构造并发送 `heartbeat` builtin
---
### YNX-0802 实现 Server heartbeat 接收与记录
**状态**
- [x] 已完成2026-04-08
**目标**
- Server 能更新客户端最近存活时间
**子任务**
- 接收 heartbeat
- 校验来源已认证
- 更新 `lastHeartbeatAt`
- 可选返回 `heartbeat_ack`
**验收标准**
- 收到心跳后客户端状态可维持在线
**已完成内容**
- Server runtime 已接入 `heartbeat` 处理,校验 allowlist 与认证状态
- 记录 `lastHeartbeatAt` 并回发 `heartbeat_ack`online 状态)
---
### YNX-0803 实现 Server liveness sweep
**状态**
- [x] 已完成2026-04-08
**目标**
- Server 能周期性评估 online / unstable / offline
**子任务**
- 增加 30~60s sweep timer
- 7 分钟无心跳标记 unstable
- 11 分钟无心跳标记 offline
- offline 时发送 `disconnect_notice` 并断开连接
**验收标准**
- 状态转移符合文档定义
**已完成内容**
- 已在 `Yonexus.Server/plugin/core/runtime.ts` 增加可配置的 liveness sweep timer默认 30s
- 已实现基于 `lastHeartbeatAt``online -> unstable -> offline` 状态判定
- 已在进入 `unstable` 时下发 `status_update(heartbeat_timeout_7m)`
- 已在进入 `offline` 时下发 `disconnect_notice(heartbeat_timeout_11m)`、关闭连接并清理 session
- 状态变化后会持久化,避免 sweep 结果只停留在内存中
---
## Phase 9 — 规则消息与 API
### YNX-0901 实现 Client rule registry
**状态**
- [x] 已完成2026-04-08
**目标**
- Client 侧支持应用层规则分发
**子任务**
- 实现 `registerRule(rule, processor)`
- 禁止 `builtin`
- 默认禁止重复注册
- 按 exact match 分发
**验收标准**
- 命中规则时正确调用处理器
- 非法注册被拒绝
**已完成内容**
- 已新增 `Yonexus.Client/plugin/core/rules.ts`
- 已实现 `registerRule()` / `hasRule()` / `dispatch()` / `getRules()`
- 已复用协议 codec 校验 rule identifier拒绝空值、非法标识符与保留字 `builtin`
- 已通过 `ClientRuleRegistryError` 固化重复注册与非法注册错误语义
- 已从 `Yonexus.Client/plugin/index.ts` 导出 rule registry 相关类型与工厂
---
### YNX-0902 实现 Server rule registry
**状态**
- [x] 已完成2026-04-08
**目标**
- Server 侧支持应用层规则分发
**子任务**
- 实现 `registerRule(rule, processor)`
- 禁止 `builtin`
- 默认禁止重复注册
- 按 exact match 分发
**验收标准**
- 规则注册与调用行为一致
**已完成内容**
- 已新增 `Yonexus.Server/plugin/core/rules.ts`
- 已实现面向服务端重写消息格式的 `registerRule()` / `hasRule()` / `dispatch()` / `getRules()`
- 已通过 `parseRewrittenRuleMessage()` 强制 server dispatch 处理 `${rule}::${sender}::${content}` 形态
- 已通过 `ServerRuleRegistryError` 固化保留字与重复注册的拒绝行为
- 已从 `Yonexus.Server/plugin/index.ts` 导出 rule registry 相关类型与工厂
---
### YNX-0903 实现 `sendMessageToServer(message)`
**状态**
- [x] 已完成2026-04-08
**目标**
- 暴露 Client 到 Server 的发送 API
**已完成内容**
- 已在 `YonexusClientRuntime` 添加 `sendMessageToServer(message)` 方法
- 已添加 `sendRuleMessage(ruleIdentifier, content)` 辅助方法
- 已校验连接/认证状态,未连接时返回 false
- 已验证消息格式(拒绝 builtin:: 前缀,要求 :: 分隔符)
- 已复用 `encodeRuleMessage` 进行类型安全的消息编码
---
### YNX-0904 实现 `sendMessageToClient(identifier, message)`
**状态**
- [x] 已完成2026-04-08
**目标**
- 暴露 Server 到指定 Client 的发送 API
**已完成内容**
- 已在 `YonexusServerRuntime` 添加 `sendMessageToClient(identifier, message)` 方法
- 已添加 `sendRuleMessageToClient(identifier, ruleIdentifier, content)` 辅助方法
- 已校验目标 client 在线且已认证,离线时返回 false
- 已验证消息格式(拒绝 builtin:: 前缀,要求 :: 分隔符)
- 已复用 `encodeRewrittenRuleMessage` 进行类型安全的消息编码
---
### YNX-0905 实现 Server 入站消息重写
**状态**
- [x] 已完成2026-04-08
**目标**
- 把客户端来的消息重写成带 sender 标识的形式
**已完成内容**
- 已在 `YonexusServerRuntime` 添加 `handleRuleMessage(connection, raw)` 私有方法
- 已更新 `handleMessage` 入口,非 builtin 消息自动进入 rule message 处理流程
- 已实现 sender identifier 识别(从 connection 或 session 中解析)
- 已使用 `parseRuleMessage` + `encodeRewrittenRuleMessage` 完成消息重写
- 重写格式:`${rule}::${content}` -> `${rule}::${sender}::${content}`
- 已校验客户端认证状态,未认证客户端发送 rule message 会被断开连接
---
## Phase 10 — 安全与鲁棒性
### YNX-1001 实现敏感信息脱敏日志
**状态**
- [x] 已完成2026-04-08
**目标**
- 避免 secret、私钥、proof 原文进入日志
**子任务**
- 定义 redaction 工具
- 覆盖 pairing、auth、error 日志路径
- 对外只保留必要上下文
**验收标准**
- 关键敏感值不会明文打印
**已完成内容**
- 已新增 `Yonexus.Server/plugin/core/logging.ts`,提供 `redactSecret()``redactPairingCode()``redactKey()` 与通用 `safeErrorMessage()`
- 已将 Server 侧 Discord pairing notification stub 改为输出结构化日志,并对 pairing code 做脱敏显示
- 已将 Server transport 的 WebSocket error 日志统一改为经 `safeErrorMessage()` 处理后的安全错误信息
- 当前仍未覆盖所有未来 auth/persistence 日志点,但 v1 现有显式日志路径已不再直接打印配对码原文
---
### YNX-1002 实现 malformed / unsupported / unauthorized 防御
**状态**
- [x] 已完成2026-04-08
**目标**
- 所有非法输入都能被可控拒绝
**子任务**
- malformed json
- 缺字段 payload
- unsupported protocol version
- unauthorized identifier
- 非法 builtin type
**验收标准**
- 错误不会导致进程崩溃
- 客户端能收到明确错误反馈或断开
**已完成内容**
- Server runtime 已为 builtin 解码增加 `CodecError` 捕获malformed builtin message 会返回 `error(MALFORMED_MESSAGE)` 而不是直接抛出
- Server runtime 已为未支持的 builtin `type` 返回显式错误响应,避免静默吞掉非法协议帧
- Client runtime 已为 builtin 解码增加容错,不再因为坏帧直接抛出;当前会记录最近一次失败原因供上层状态观察
- Client / Server 的 rule message 发送校验已收敛到共享 codec而不再依赖脆弱的本地正则片段判断
---
### YNX-1003 实现单 identifier 单活跃连接策略
**状态**
- [x] 已完成2026-04-08
**目标**
- 同一 client identifier 只允许一个活跃认证连接
**子任务**
- 定义旧连接替换策略
- 新连接成功认证后踢掉旧连接
- 避免竞态导致双在线
**验收标准**
- 任意时刻同一 identifier 只有一个有效 session
**已完成内容**
- 已重构 `YonexusServerTransport`
- `tempConnections` 改为 Map 结构,跟踪未认证连接
- 新增 `assignIdentifierToTemp()`hello 时仅分配 identifier不进入认证注册表
- 新增 `promoteToAuthenticated()`:认证成功后晋升为正式连接,此时才关闭旧连接
- 新增 `removeTempConnection()`:认证失败时清理临时连接
- 已更新 `runtime.ts`
- hello 处理使用 `assignIdentifierToTemp()` 代替 `registerConnection()`
- auth_success 后调用 `promoteToAuthenticated()` 完成连接晋升
- **安全改进**:未认证连接无法踢掉已认证连接,防止连接劫持攻击
---
### YNX-1004 实现重启恢复策略
**状态**
- [x] 已完成2026-04-08
**目标**
- 重启后行为可预期且文档一致
**子任务**
- 恢复 durable trust records
- 清理或重建 rolling windows
- 明确 pending pairing 如何恢复
- 明确 active connection 状态如何重建
**验收标准**
- 重启后的认证/配对行为稳定可解释
**已完成内容**
- **持久化恢复**`YonexusServerRuntime.start()` 加载持久化记录,恢复所有 client records
- **allowlist 同步**:对配置中的 `followerIdentifiers` 自动创建缺失的初始记录
- **rolling windows 清理**`deserializeClientRecord()` 明确清空 `recentNonces``recentHandshakeAttempts`
- v1 设计:安全窗口仅内存驻留,重启后重建,防止旧 nonce 积压
- **pending pairing 恢复**:保留 `pairingStatus=pending``pairingCode`,支持重启后继续配对流程
- **连接状态重建**
- 所有连接状态标记为 `offline`WebSocket 连接不可恢复)
- `lastHeartbeatAt` 保留liveness sweep 会根据其判断状态转移
- **已文档化**:在 `persistence.ts``types.ts` 中以 JSDoc 注释明确重启语义
---
## Phase 11 — 测试与联调
### YNX-1101 编写协议单元测试
**状态**
- [x] 已完成2026-04-09
**目标**
- 覆盖编解码、字段校验、错误码
**已完成内容**
- 新增 `Yonexus.Protocol/tests/codec.test.ts`
- 覆盖 builtin 编解码、rule message/rewritten message 解析、保留字与非法标识符校验
- 覆盖 encode/parse 边界、malformed message 报错与 `isBuiltinMessage` 行为
### YNX-1102 编写 Server 单元测试
**状态**
- [x] 已完成2026-04-09
**目标**
- 覆盖 registry、pairing、auth、heartbeat sweep
**已完成内容**
- 已为 `Yonexus.Server` 接入 `vitest` 测试基础设施(`package.json` + `vitest.config.ts`
- 已新增 `tests/pairing-and-rules.test.ts`
- 已覆盖 pairing request 创建、有效/无效/过期 code 校验、通知状态迁移
- 已覆盖 server rule registry 的 exact-match dispatch、保留字拒绝、重复注册拒绝
- 已新增 `tests/pairing-auth-liveness.test.ts`
- 已覆盖 auth 校验public key/timestamp/nonce/rate limit/签名)与心跳 liveness 判定
- 已新增 `tests/runtime-flow.test.ts`
- 已覆盖 hello -> pair_request、pair_confirm -> auth_request -> heartbeat、未认证 rule message 拒绝、liveness sweep 触发 `status_update` / `disconnect_notice`
- 补齐测试过程中暴露的服务端 publicKey 标准化问题hello 阶段已统一 trim避免 PEM 尾部换行导致 `auth_request` 误判 `invalid_signature`
### YNX-1103 编写 Client 单元测试
**状态**
- [x] 已完成2026-04-09
**目标**
- 覆盖状态机、keypair、auth 构造、heartbeat timer
**已完成内容**
- 已为 `Yonexus.Client` 接入 `vitest` 测试基础设施(`package.json` + `vitest.config.ts`
- 已新增 `tests/state-and-rules.test.ts`
- 已覆盖 client state 文件缺失初始化、状态保存/回读
- 已覆盖 `ensureClientKeyPair()` 的首次生成/重复调用复用,以及签名/验签基本链路
- 已覆盖 client rule registry 的 dispatch、保留字拒绝、重复注册拒绝
- 已新增 `tests/state-auth-heartbeat.test.ts`
- 已覆盖 auth_request signing input、nonce/timestamp 校验、状态机迁移与 heartbeat scheduler 行为
- 已新增 `tests/runtime-flow.test.ts`
- 已覆盖启动时加载 state + 自动补 keypair、`hello_ack`/`pair_request`/`pair_success`/`auth_success` 协作链路、`auth_failed`/`re_pair_required` 的 trust reset以及认证后 heartbeat 发送门禁
### YNX-1104 编写 Server-Client 集成测试
**状态**
- [x] 已完成2026-04-09
**目标**
- 覆盖首次配对、正常重连、认证失败、心跳超时、re-pair
**已完成内容**
- 已创建 `tests/integration/framework.test.ts` 集成测试框架
- 提供 `MockTransportPair` 模拟 Server-Client 网络通信
- 提供 `createIntegrationTestContext()` 快速创建集成测试环境
- 已修正集成测试框架中的时间推进问题,`advanceTime()` 现在会真实驱动 Server / Client runtime 的 `now()`
- 已实现以下集成测试用例:
- 首次配对完整流程hello → pair_request → pair_confirm → auth → heartbeat
- 带凭证的重连流程(跳过配对直接认证)
- 认证后的心跳交换验证
- 心跳超时触发 `unstable` / `offline``disconnect_notice`
- nonce collision 触发 `re_pair_required` 后 client 回退到 `pair_required`
**待完成**
- 并发连接等剩余边界场景
- 真实 WebSocket 传输层集成测试(可选)
---
### YNX-1104a 细化:首次配对集成测试
**状态**
- [x] 已完成2026-04-09
**已完成内容**
- `First-Time Pairing Flow` 测试套件
- 验证端到端的配对与认证状态迁移
---
### YNX-1104b 细化:重连集成测试
**状态**
- [x] 已完成2026-04-09
**已完成内容**
- `Reconnection Flow` 测试套件
- 验证已配对客户端跳过配对直接进入认证
### YNX-1105 编写失败路径测试矩阵
**状态**
- [x] 已完成2026-04-09
**进展补充2026-04-09**
- 基于本轮锁定的 v1 边界,`AF-04` 已明确按 v1 语义并入 `invalid_signature`,不再作为“未完成测试缺口”单独追踪;若后续要恢复 `invalid_secret`,需先同步调整协议与实现
- `RP-03`(管理员主动撤销)与 `RP-04`key rotation继续保留为 v2+ 议题,与 `PLAN.md` / `FEAT.md` 的 v1 边界保持一致
- 已补充 `CF-05``hello` 缺失 payload 时返回 `MALFORMED_MESSAGE` 且保持连接可继续诊断
- 已补充 `SR-04`Client 首次运行/无凭证状态会自动补 keypair并在 `hello_ack(pair_required)` 后进入完整配对流,不需要手工预置 state
- 已同步将 `CF-07`(保留字 rule 注册拒绝)在失败路径矩阵里标记为已覆盖,和现有 Client/Server rule registry 测试保持一致
- 本轮新增 `CF-01` / `CF-02`:补齐 client transport 在网络分区与首次建连失败时的指数退避重连测试
- 本轮新增 `SR-02`:补齐 server restart 后 active session 不恢复、但 durable trust record 保留且客户端需要重新 hello/auth 的恢复测试
- 已新增 umbrella 仓库一键回归入口 `scripts/validate-v1.sh`,把 Protocol / Server / Client 的最小 v1 验证串成单次执行
- 本轮继续补齐 `Yonexus.Protocol` 本地依赖与 `check` 脚本,使 umbrella 校验链路覆盖协议层类型检查
- 已将 `scripts/validate-v1.sh` 调整为缺依赖时自动执行 `npm ci` / `npm install`,减少首次回归阻塞
- 已完成一次完整 umbrella 回归:`Yonexus.Protocol` / `Yonexus.Server` / `Yonexus.Client` 的 check + test 全绿
- 已顺手修复本轮回归暴露的 TypeScript 收尾问题Protocol payload 泛型约束、Server `pairedAt` 持久化字段、Client/Server config 严格模式报错、测试态 runtime 通知服务注入
**目标**
- 系统性覆盖 pairing/auth 失败路径
**重点场景**
- pairing code 错误
- pairing 过期
- DM 发送失败
- stale timestamp
- future timestamp
- nonce collision
- handshake rate limit
- unknown identifier
- duplicate connection
**验收标准**
- 核心安全路径都有自动化测试
**已完成内容**
- 已创建 `tests/failure-path/MATRIX.md` 失败路径测试矩阵文档
- 定义 PF-01~PF-10Pairing Failures
- 定义 AF-01~AF-11Authentication Failures
- 定义 RP-01~RP-04Re-pairing Triggers
- 定义 CF-01~CF-07Connection Failures
- 定义 HF-01~HF-04Heartbeat Failures
- 定义 SR-01~SR-06State Recovery
- 标记优先级(🔴 Phase 1 关键安全路径)
- 已创建 `tests/failure-path/pairing-failures.test.ts`
- PF-01: 无效配对码及重试机制
- PF-02: 过期配对码清理
- PF-03: 非 allowlist 标识符拒绝
- PF-04: 管理员通知失败处理
- PF-05: 空/空白配对码拒绝
- PF-06: 畸形 pair_confirm 载荷处理
- PF-07: 已配对客户端重复配对保护
- Edge Cases: 并发配对、过期清理验证
- 已新增 `Yonexus.Server/tests/auth-failures.test.ts`
- AF-01 / AF-02unknown identifier、not_paired
- AF-03 / AF-09 / AF-11invalid signature、wrong public key、tampered proof
- AF-05 / AF-06stale / future timestamp
- AF-07 / AF-08nonce collision / rate limit 触发 re_pair_required
- AF-10malformed auth_request payload
- 覆盖 re_pair 后 secret 清理与 pairingStatus=revoked
- 已同步更新 `tests/failure-path/MATRIX.md` 的 PF / AF / RP / HF 状态标记与当前备注
- 已新增 `Yonexus.Server/tests/connection-heartbeat-failures.test.ts`
- CF-06未认证 rule message 会关闭连接
- HF-03认证前心跳会返回 `AUTH_FAILED`
- HF-04无会话心跳会返回 `AUTH_FAILED`
- 已新增 `Yonexus.Server/tests/state-recovery.test.ts`
- SR-01 / PF-09server restart with pending pairing验证 pending pairing 与 pairing code 在重启后保留hello 重新进入 `waiting_pair_confirm`
- SR-05损坏的 server store 会抛出 `YonexusServerStoreCorruptionError`
- 已扩展 `Yonexus.Client/tests/state-and-rules.test.ts`
- SR-06损坏的 client state 会抛出 `YonexusClientStateCorruptionError`
- 已同步更新 `tests/failure-path/MATRIX.md`,标记 PF-09、SR-01、SR-05、SR-06 为已覆盖
- 已新增 `Yonexus.Server/tests/connection-heartbeat-failures.test.ts` 补齐:
- CF-03重复认证连接晋升时关闭旧连接并保留新连接
- CF-04协议版本不匹配时返回 `UNSUPPORTED_PROTOCOL_VERSION` 并主动断开
- 已新增 `Yonexus.Client/tests/runtime-flow.test.ts` 恢复场景:
- SR-03客户端带既有 secret + keypair 重启后直接进入 auth flow不重新配对
- 已同步更新 `tests/failure-path/MATRIX.md`,标记 RP-02、CF-03、CF-04、SR-03 为已覆盖
- 已新增 `Yonexus.Server/tests/runtime-flow.test.ts`
- CF-05`hello` 缺失 payload 时返回 `error(MALFORMED_MESSAGE)` 且不主动断开连接
- 已新增 `Yonexus.Client/tests/runtime-flow.test.ts`
- SR-04客户端在无 secret/首次运行状态下启动后可自动进入 `pair_required`,无需手工 bootstrap 本地 state
- 已同步更新 `tests/failure-path/MATRIX.md`,标记 CF-05、CF-07、SR-04 为已覆盖
- 已新增 `Yonexus.Client/tests/transport-reconnect.test.ts`
- CF-02首次连接失败时按 1s → 2s 指数退避继续重试,成功后恢复 connected
- CF-01已建立连接在异常 closenetwork partition后会按退避策略发起重连
- 已扩展 `Yonexus.Server/tests/state-recovery.test.ts`
- SR-02server restart 后不恢复内存 session保留 durable paired trust并要求 client 重新 `hello` 后进入 `auth_required`
- 已新增 `Yonexus.Server/tests/notifications.test.ts`
- PF-04覆盖 Discord DM 消息格式、成功发送、DM channel 创建失败、配置缺失
- 已扩展 `tests/failure-path/pairing-failures.test.ts`
- PF-08已配对且在线的 client 再次发起 `pair_confirm` 时会被拒绝,且旧 trust material 保持不变
- 已扩展 `Yonexus.Client/tests/runtime-flow.test.ts`
- PF-10client 在 waiting_pair_confirm 阶段重启后,可重新 hello 并恢复到等待 out-of-band pairing code 的流程
- 已同步更新 `tests/failure-path/MATRIX.md`,标记 CF-01、CF-02、PF-08、PF-10、SR-02 为已覆盖
**剩余说明(不阻塞 v1**
- RP-03 / RP-04管理员主动撤销与 key rotation 语义仍未实现,继续按 v2+ 保留
- PF-04 当前已覆盖运行时失败路径与通知服务单测,但真实 Discord 环境 smoke test 仍属于后续非阻塞验证项
---
## Phase 12 — 文档与交付
### YNX-1201 补齐 Server README
**状态**
- [x] 已完成2026-04-08
**目标**
- Server 仓库可独立被安装与使用
**已完成内容**
- 已补齐 `Yonexus.Server/README.md`
- 已写明当前实现范围、配置字段、启动/连接流程、公开 API、持久化语义与开发方式
- 已明确当前限制项(真实 Discord DM、测试覆盖、生命周期集成等避免 README 过度承诺
### YNX-1202 补齐 Client README
**状态**
- [x] 已完成2026-04-08
**目标**
- Client 仓库可独立被安装与使用
**已完成内容**
- 已补齐 `Yonexus.Client/README.md`
- 已写明配置模型、启动/配对/认证流程、公开 API、本地 state 结构与开发方式
- 已明确当前限制项(测试、配对输入 UX、生命周期集成等方便后续交接和联调
### YNX-1203 输出部署文档
**状态**
- [x] 已完成2026-04-08
**目标**
- 写清楚单主多从部署方式、配置示例、配对流程
**已完成内容**
- 新增 `DEPLOYMENT.md`覆盖拓扑、子模块同步、Server/Client 安装、配置示例与配对流程
### YNX-1204 输出运维排障文档
**状态**
- [x] 已完成2026-04-08
**目标**
- 写清楚常见报错、状态含义、恢复步骤
**已完成内容**
- 新增 `OPERATIONS.md`,覆盖状态说明、常见错误与恢复建议
### YNX-1205 输出协议测试与验收清单
**状态**
- [x] 已完成2026-04-08
**目标**
- 让后续改动有统一回归基线
**已完成内容**
- 已新增 `ACCEPTANCE.md`
- 已按协议层、Server、Client、联调、失败路径回归矩阵拆分验收项
- 已把 `YNX-1101`~`YNX-1105` 与具体验收/测试目标建立对应关系,方便后续补自动化测试时直接对照
---
## 推荐执行顺序(最小闭环)
### 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 最小握手
这样最快能拿到一个“能启动、能连接、能判断下一步动作”的基础闭环。