diff --git a/FEAT.md b/FEAT.md index 09d485c..326f278 100644 --- a/FEAT.md +++ b/FEAT.md @@ -10,6 +10,33 @@ This repository now targets the split-plugin architecture only. --- +## Shared Terminology and v1 Scope + +Canonical terms used across the project: +- `identifier`: unique logical client name +- `rule_identifier`: exact-match application route key +- `builtin`: reserved protocol/system route namespace +- `pairingCode`: short-lived out-of-band pairing code +- `secret`: shared secret issued after pairing +- `publicKey` / `privateKey`: client signing keypair + +Locked v1 decisions: +- `heartbeat_ack` is optional +- client reconnect uses exponential backoff +- rule matching is exact-match only +- offline sends fail immediately instead of queueing +- `mainHost` is expected to be a full `ws://` or `wss://` URL + +Explicit v1 non-goals: +- multi-server topology +- direct client-to-client sockets +- offline queueing guarantees +- advanced rule matching +- management UI +- admin approval control plane beyond human relay of pairing codes + +--- + ## 1. Yonexus.Server Features ### 1.1 Server Runtime diff --git a/PLAN.md b/PLAN.md index 4d53cd2..3d22891 100644 --- a/PLAN.md +++ b/PLAN.md @@ -124,6 +124,22 @@ Semantics: --- +## 4.4 Shared Terminology Baseline + +These names are normative across umbrella docs, protocol docs, and implementation repos: + +- `identifier`: the unique logical name of a client/follower instance. +- `rule_identifier`: the exact-match application route key. +- `builtin`: reserved rule namespace for protocol/system frames. +- `pairingCode`: short-lived out-of-band code delivered to the human admin. +- `secret`: server-issued shared secret used for reconnect proof construction. +- `publicKey` / `privateKey`: client-held signing keypair. +- `nextAction`: server-directed next step returned by `hello_ack`. + +Implementations should avoid introducing alternative synonyms for these fields unless there is a versioned migration plan. + +--- + ## 5. Runtime Lifecycle ## 5.1 Yonexus.Server Startup @@ -551,25 +567,39 @@ Not required in the first version unless explicitly added later: - direct client-to-client sockets - multi-server clustering - distributed consensus +- offline message queues or guaranteed delivery to disconnected clients +- advanced rule matching beyond exact string match - message ordering guarantees across reconnects - end-to-end payload encryption beyond the pairing/authentication requirements - management UI +- admin-side approve/deny control plane beyond human relay of pairing codes +- encryption-at-rest hardening beyond documenting current local storage limitations --- -## 16. Open Questions To Confirm Later +## 16. v1 Decisions Locked for Current Implementation -1. Exact signing algorithm: - - Ed25519 is a strong default candidate -2. Should `mainHost` accept only full WebSocket URLs or also raw `ip:port` strings? -3. Is human code relay sufficient for v1 pairing, or should admin approve/deny controls be added later? -4. On unsafe condition, should the old public key be retained or should the client generate a new keypair? -5. Should offline clients support queued outbound messages from server, or should sends fail immediately? -6. Are rule identifiers exact strings only, or should regex/prefix matching exist later? +The following implementation-boundary decisions are now treated as settled for v1: + +1. Signing algorithm default: Ed25519. +2. `mainHost` should be configured as a full `ws://` or `wss://` URL in v1. +3. Human relay of the pairing code is sufficient for v1; richer admin approve/deny control can wait. +4. `heartbeat_ack` remains optional. +5. Client reconnect uses exponential backoff. +6. Rule identifiers are exact-match strings only in v1. +7. Outbound sends to offline clients fail immediately rather than queueing. + +## 17. Open Questions To Confirm Later + +1. On unsafe condition, should the old public key be retained or should the client generate a new keypair? +2. Should future versions support explicit key rotation without full re-pairing? +3. Should offline clients support queued outbound messages from server in a later version? +4. Are richer admin approval workflows worth adding after v1 stabilizes? +5. Should encryption-at-rest become a hard requirement in v2? --- -## 17. Immediate Next Deliverables +## 18. Immediate Next Deliverables After this plan, the next files to create should be: - `FEAT.md` — feature checklist derived from this plan diff --git a/PROTOCOL.md b/PROTOCOL.md index 4103dd7..466e871 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -26,6 +26,22 @@ Important security rule: --- +## 1.1 Canonical Terminology + +These names are treated as protocol-level canonical terms: + +- `identifier`: unique logical identity of a Yonexus client instance. +- `rule_identifier`: exact-match routing key for application messages. +- `builtin`: reserved protocol namespace used only for Yonexus control frames. +- `pairingCode`: short-lived out-of-band code generated by the server for human-mediated pairing. +- `secret`: server-issued shared secret used in reconnect authentication proof construction. +- `publicKey` / `privateKey`: client signing keypair. +- `nextAction`: the server's directed next step in `hello_ack`. + +The protocol and implementation repos should prefer these exact names over synonyms. + +--- + ## 2. Transport Transport is WebSocket. @@ -35,13 +51,12 @@ Transport is WebSocket. - protocol frames are UTF-8 text in v1 - binary frames are not required in v1 -Client connects to configured `mainHost`, which may be: +Client connects to configured `mainHost`, which in v1 should be a full WebSocket URL: - `ws://host:port/path` - `wss://host:port/path` -- or raw `host:port` if normalized by implementation Recommended canonical config: -- prefer full WebSocket URL +- require/prefer a full WebSocket URL in v1 rather than raw `host:port` --- @@ -426,6 +441,9 @@ builtin::{ ### `heartbeat_ack` Optional response by `Yonexus.Server`. +v1 policy: +- `heartbeat_ack` may be enabled by the server but clients must not require it for healthy operation + Example: ```text @@ -624,6 +642,9 @@ Dispatch algorithm: 4. invoke the first exact match 5. ignore/log if no match is found +v1 policy: +- rule matching is exact string match only; prefix, wildcard, and regex routing are out of scope + Processor input: - on client: `${rule_identifier}::${message_content}` - on server for client-originated messages: `${rule_identifier}::${sender_identifier}::${message_content}` diff --git a/README.md b/README.md index eada631..2c124eb 100644 --- a/README.md +++ b/README.md @@ -154,12 +154,46 @@ Reserved rule: `builtin` --- +## Shared Terminology + +To keep the umbrella repo, protocol repo, and both plugin repos aligned, Yonexus uses these terms consistently: + +- `identifier`: the stable logical name of a follower/client instance, unique within one Yonexus network. +- `rule_identifier`: the exact-match application routing key used in `${rule_identifier}::${message_content}`. +- `builtin`: the reserved rule namespace for Yonexus protocol/control messages only. +- `pairingCode`: the short-lived out-of-band code generated by `Yonexus.Server` and delivered to a human admin by Discord DM. +- `secret`: the server-issued shared secret established after successful pairing and used in reconnect authentication proof construction. +- `publicKey` / `privateKey`: the client-owned signing keypair used for auth proof signing and verification. +- `nextAction`: the server decision returned in `hello_ack`, currently one of `pair_required`, `waiting_pair_confirm`, `auth_required`, or `rejected`. + +## v1 Scope Boundaries + +In scope for v1: +- WebSocket transport between one server and one or more clients +- out-of-band pairing via Discord DM to a human administrator +- signed reconnect authentication using `secret + nonce + timestamp` +- heartbeat/liveness tracking (`online | unstable | offline`) +- exact-match rule dispatch +- lightweight persistence for trust/state material +- optional `heartbeat_ack` +- exponential reconnect backoff on the client side + +Explicitly out of scope for v1: +- multi-server topology +- direct client-to-client sockets +- offline message queues / delivery guarantees +- advanced rule matching (prefix/regex/wildcard) +- management UI +- distributed consensus / clustering +- automatic admin approve/deny workflows beyond human relay of the pairing code +- encryption-at-rest hardening beyond documenting local sensitive storage behavior + ## Status -- planning/specification stage -- split-plugin architecture defined -- protocol draft defined in `Yonexus.Protocol` -- implementation not started yet +- umbrella/specification repo is aligned with the split architecture +- core implementation work is underway in `Yonexus.Server`, `Yonexus.Client`, and `Yonexus.Protocol` +- protocol/types/codec/test scaffolding already exists in `Yonexus.Protocol` +- runtime, transport, pairing, auth, heartbeat, rule dispatch, and test coverage are largely implemented in submodules; remaining work is focused on boundary cleanup and leftover failure-path coverage --- diff --git a/TASKLIST.md b/TASKLIST.md index 28cded5..645c817 100644 --- a/TASKLIST.md +++ b/TASKLIST.md @@ -22,6 +22,9 @@ ## Phase 0 — 仓库与规范对齐 ### YNX-0001 统一仓库定位与术语 +**状态** +- [x] 已完成(2026-04-09) + **目标** - 统一文档中对 Yonexus、Yonexus.Server、Yonexus.Client、Yonexus.Protocol 的描述 - 明确这是“umbrella + 三个独立仓库/子模块”的模型 @@ -35,9 +38,17 @@ - 核心文档不存在角色冲突或架构冲突描述 - 协议字段名称在文档中保持一致 +**已完成内容** +- 已在 `README.md` 新增 Shared Terminology 区块,统一 umbrella repo 对核心术语的定义 +- 已在 `PLAN.md` 新增 `Shared Terminology Baseline`,明确这些字段名为跨仓库规范用语 +- 已在 `FEAT.md` 与 `PROTOCOL.md` 同步补齐 canonical terminology,避免后续实现和文档再出现同义词漂移 + --- ### YNX-0002 定义 v1 实现边界 +**状态** +- [x] 已完成(2026-04-09) + **目标** - 把“必须做”和“以后再说”彻底分开 @@ -51,6 +62,11 @@ - 有一份可执行的 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 — 协议落地与共享契约 @@ -1095,6 +1111,10 @@ **状态** - [x] 持续补齐中,关键路径已覆盖并继续收尾连接/恢复场景(2026-04-09) +**进展补充(2026-04-09)** +- 基于本轮锁定的 v1 边界,`AF-04` 暂保持未覆盖并标记为“语义待确认”,因为当前实现仍把错误 secret 统一归入 `invalid_signature` +- `RP-04`(key rotation)继续保留为 v2+ 议题,与本轮在 `PLAN.md` / `FEAT.md` 固化的 v1 边界保持一致 + **目标** - 系统性覆盖 pairing/auth 失败路径 diff --git a/tests/failure-path/MATRIX.md b/tests/failure-path/MATRIX.md index 105170f..bc5bc38 100644 --- a/tests/failure-path/MATRIX.md +++ b/tests/failure-path/MATRIX.md @@ -133,6 +133,7 @@ npm test -- failure-paths ### Current Notes - AF-04 (`invalid_secret`) 仍未单独覆盖:现有实现把“错误 secret 导致的验签失败”统一落到 `invalid_signature`,是否拆分错误码仍待确认。 +- RP-04(key rotation)当前仍视为 v2+ 议题;v1 尚未承诺“无重配对换 key”语义,因此暂不强行补测试。 - 本轮已补齐 AF-01/02/03/05/06/09/10/11、RP-01/02、CF-03/04、HF-01/02、PF-09、SR-01/03/05/06。 ### Adding New Test Cases