Skip to content

0.7.0 review fixes#2

Merged
serg-plusplus merged 15 commits into
mainfrom
0.7.0-review-fixes
Jul 12, 2026
Merged

0.7.0 review fixes#2
serg-plusplus merged 15 commits into
mainfrom
0.7.0-review-fixes

Conversation

@Cyace84

@Cyace84 Cyace84 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Cyace84 added 8 commits July 6, 2026 22:00
- Rewrite spec/protocol.md port-complete: D1 deferred reset, D2 bounded
  seen-nonce set, epoch uint32 no-wrap, frame limits (tag-included),
  MAX_ID_LEN=64, error coercion rules, mandatory t-check reflection defense,
  fix step 7 (was contradicting code on PSK zeroing)
- Add spec/assessment.md: public security assessment (method, verified
  properties, 7 residual risks with status), linked from README/security.md/index.md
- Add real KAT test vectors via scripts/gen-vectors.mjs, pinned by
  test/unit/vectors.test.ts (4 cross-checked tests)
- gitignore review-*
- C5: INPUT_VALIDATION et al are server-side, arrive as RemoteRPCError
  (README catch comment + api.md error-code note)
- C7: zod is a bundled dependency, not a peer dependency (getting-started)
- C9: Channel.receive tolerates void return, with leak warning (api.md)
…ndow (D2), abortPending (F3)

client.ts:
- F1/Option A: no auto-retry. A TIMEOUT (outcome unknown) or CHANNEL send
  error resets the session but is NOT resent — the error surfaces so the
  caller, which alone knows idempotency, decides. Removes the silent
  double-execution hazard (C1). Guardrail (CLIENT)/SESSION never reset.
- C4: wrap channel.send rejections in RPCError('CHANNEL', ..., { cause }).
- C8: drop (state as any) cast + @todo typo (lived in the old retry block).
- F3: abortPending(err?) — reject all pending + fail in-progress handshake
  with a retryable code, zero keys, state=idle (not closed). Returns
  { api, abortPending, destroy }. Default err = RPCError('CHANNEL','Channel down').
- Fix: onReplyError only fails the handshake while state==='handshaking'
  (client-side analog of D1) — a stale/injected reply on the current epoch
  can no longer tear down a session a concurrent valid reply established.

server.ts:
- D1 deferred reset: a hello opens an ATTEMPT on attempt-local ephemeral
  keys; the live session serves throughout and is swapped in atomically
  only after full validation. A garbage/bad-sig hello can no longer displace
  an established session. attemptEpoch (per hello) vs epoch (per publish).
- D2 bounded seen-nonce set: reject in-session replays. Nonce recorded only
  after Poly1305 verifies; FIFO ring, default replayWindow=4096, 0=off;
  cleared on rekey. New ServerOptions.replayWindow.

common.ts: RPCError gains optional 4th arg { cause } (native Error cause).

Suite 249/249.
…lay window

- transport-lifecycle.test.ts: lost reply -> TIMEOUT + handler runs once (no
  resend); send failure -> CHANNEL + never executes; RemoteRPCError passthrough
  without reset; abortPending rejects in-flight with CHANNEL and keeps client
  usable / custom err fails in-progress handshake / no-op after destroy.
- dos-attacks: C1 regression — maxPending overflow keeps exec==4, hello==1.
- deferred-reset.test.ts (D1): garbage hello + Ed25519 bad-auth hello can't
  displace a live session; in-flight call survives an injected hello.
- replay-window.test.ts (D2): replay dropped (exec once); replayWindow:0
  re-executes; replay older than window re-executes (FIFO boundary).
- client.ts: sendRequest also wraps a SYNCHRONOUS channel.send throw in
  RPCError('CHANNEL') (not just async rejection).

Suite 262/262.
… D1/D2 status

- protocol.md: 'Auto-retry semantics' -> 'Failure handling (no auto-retry)'
  (Option A: reset-no-resend; why-no-resend / why-still-reset), abortPending
  subsection, state-machine + failure-modes row + checklist bullet.
- api.md: client return type gains abortPending; Failure-handling section;
  replayWindow ServerOptions row; CHANNEL error-code row; timeout/receive text.
- security.md: replay-within-session now describes the bounded seen-nonce
  window; defense table row updated.
- assessment.md: risks #1/#2/#3 flipped to 'fixed in 0.7.0' with residuals;
  version 0.6.1->0.7.0, 245->262 tests.
- README / index.md / getting-started.md: no silent resend wording.
- integrations.md: browser-WS readyState guard + onclose->abortPending (F4);
  drop 'retry' from adapter surface.
- Updated assessment and protocol documentation to reflect the new make-before-break approach for session management.
- Modified server implementation to support candidate sessions that run alongside live sessions, ensuring that duplicate or stale hellos cannot retire the live session.
- Introduced new tests for session continuity, validating that replayed valid hellos do not disrupt established sessions and that unconfirmed candidates expire correctly.
- Improved security documentation to emphasize the importance of using high-entropy cryptographic keys instead of passwords for session secrets.
@Cyace84
Cyace84 requested a review from serg-plusplus July 7, 2026 21:38
Cyace84 added 3 commits July 10, 2026 00:54
- Removed abortPending() functionality in favor of handling timeouts with RPCAbortedError.
- Updated tests to reflect new error handling for TIMEOUT and CHANNEL errors.
- Enhanced ws-channel tests to ensure proper error throwing during down states and after close.
- Adjusted createFaultChannelPair to throw errors synchronously when the channel is down.
- Improved session continuity tests to validate genuine client resets and re-handshakes.
@serg-plusplus
serg-plusplus merged commit 809b58f into main Jul 12, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants