mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
* test(b3-6): client connection model test — fc.commands over the real stack B3-6 item 4 (Tier 3a of docs/plans/bug-detection-improvements.md). Property tests find bad functions; this repo's recurring bugs are bad orderings, and nothing generated orderings. Client/tests/unit/connection.model.test.ts drives the real connection stack — createWsClient() + wireDispatcher() + the real stores — through seven fc.commands (Connect, Disconnect, RegisterNow, Receive(id, seq), Supersede, Resync, Logout) against a minimal reference model, checking four invariants after every command: no duplicate message ids, a monotonic seq watermark (observed at the auth frame, reset only at the modelled epoch resets), a verified peer that never flips to unverified, and a superseded attempt's teardown that never kills the newer session. Only the boundaries are mocked: the Tauri IPC wire (the shared ws-mocks helper) and the LiveKit / notification / toast / identity leaves, as in dispatcher.test.ts. Seeded (OWNCORD_MODEL_SEED, default fixed) so a failure replays exactly; 150 runs of up to 30 commands, ~0.9 s for the file. A second test asserts every invariant family was actually reached, so a family that stops being reachable fails instead of silently passing. Test only — no Client/src/ change, so B7's rule holds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * docs(b3-6): evidence block for item 4 (client connection model test) Records the branch and commit, the seven commands and four invariants, the RED counterexample for each invariant family with its restored control, the GREEN runs, and the numbers (seed 20260830, numRuns 150, maxCommands 30, 1083 invariant checks, 119 ms of test time). Also notes the two spec details resolved against HEAD: RegisterNow has no client-side symbol (it is the server's hub registration, observed here as the ready-snapshot/queued-frame redelivery), and the design's aborted voice attempt is reachable from the connection layer through the dispatcher's stale voice_leave guard rather than through LiveKitSession's join generations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * test(b3-6): connection model — drop the tautological seq check, make coverage counters count the non-trivial case, guard the seed Review findings on B3-6 item 4. The invariant-2 assertion in checkInvariants compared the model to itself and could not fail, while reading as though the seq watermark were checked after every command. Deleted; the header comment now says where the real assertion lives (connectCmd, against that connect's own auth frame). Both coverage counters were counting their no-op case: exercised.seq counted the initial connect declaring last_seq 0, and exercised.verified counted the check that runs immediately after Supersede seeded the verifications itself. They now count only a resume (last_seq > 0) and a verification check that survived some other command, so "reached every invariant family" fails if only the trivial form remains. Both still hold at the default seed and at 99. A malformed OWNCORD_MODEL_SEED now throws instead of handing fast-check the NaN (or the 0 an empty variable coerces to) and running a different suite than the one that was asked for. The evidence block's "+0.4 s on the full client suite" was never measured — both full-suite runs included this file. Replaced with the file's own measured cost and the observed suite spread, which is larger than that cost. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * test(b3-6): connection model — a buffer resume replays events after auth_ok; ready only on the fresh/fallback path (Codex P2 on #1455) Verified against the server before changing anything. reconnectWriteReplay (Server/ws/serve.go:593) writes auth_ok with the replay tier and then the missed events, and never a ready; only reconnectPrecheck falling through to handleFreshConnect produces auth_ok(none) + ready. The epoch-1 fixtures record exactly that split: fresh-connect.json is auth_ok(none) -> ready -> ..., resume-replay.json is auth_ok(buffer) -> presence -> chat_message -> presence, with no ready anywhere. Codex is right. Connect now drives whichever shape the model's watermark implies: last_seq 0 takes the fresh path unchanged, last_seq > 0 takes the resume path — auth_ok with the tier, then one replayed chat_message carrying the next seq, and no ready. The replayed frame is a message that committed while we were away, or, once the id pool is exhausted, a redelivery of one already held, which is the other real replay shape. An assertion after the handshake requires that frame to be in the store: on this path the replay burst is the only thing that repairs client state, so nothing else can cover for it. RegisterNow had the same defect one step smaller — a bare ready, which the server never writes either. It now sends the full auth_ok(none) + ready handshake before the queued redelivery, so every ready in the file follows the auth_ok that precedes it on the wire, and the redelivered frame carries the server's restarted counter (OC-0032). exercised.resumeReplay joins the coverage counters, so the resume path cannot quietly stop being generated. Reverting the resume branch to the pre-fix shape fails on [Connect,Receive(id=1,seq=1),Disconnect,Connect] with "expected [ 1 ] to include 2" and on the family counter. Merely adding a ready alongside the replay still passes — recorded in the report as the honest result: that shape does not break an invariant, it just lets a snapshot do the repair the replay burst is supposed to do. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>