chore: dev-stack switches, shared e2e harness, and desktop shell rules

- `LIVE_RELOAD=false npm run dev` keeps the renderer alive across a machine
  suspend; the reload client otherwise destroys the session under test.
- `dev-peer.sh` plus a separate userdata dir runs a second local peer.
- `tools/voice-probe.js` samples peer state and RTP counters from a live
  window, persisting to localStorage so a renderer reload cannot erase it.
- e2e helpers for voice pairs, peer-role election, and a TURN relay.
- Electron single-instance and dev-client-load decisions move into rules
  files with colocated specs.
This commit is contained in:
2026-08-14 03:19:29 +02:00
parent d71e3a98da
commit e49b3ec112
41 changed files with 35947 additions and 50 deletions
+22 -1
View File
@@ -8,12 +8,21 @@ Tags help grepping: `rg '\\[attachments\\]' agents-docs/LESSONS-INDEX.md`
## Index
- A hold-on-unknown rule needs every attach site behind it — `[voice] [webrtc] [realtime]`
- Swap a live device with `replaceTrack`; an empty device list is missing evidence — `[voice] [webrtc] [devices]`
- One owner for a toggle the UI mirrors — `[voice] [state] [ui]`
- A timed-out sync round is not a clean one — `[messages] [realtime] [verification]`
- Derive a conversation id from canonical humans, never from the ids on the wire — `[direct-message] [identity]`
- Report whether a call event was delivered before showing a live call — `[direct-call] [verification]`
- Never spend a retry budget on attempts the transport cannot deliver — `[realtime] [recovery]`
- Repair a dead data channel on the live connection before rebuilding the peer — `[realtime] [webrtc] [recovery]`
- Compare peer ids only within one signal server's identity space — `[realtime] [identity] [webrtc]`
- Reproduce initiator/glare bugs with a simultaneous reconnect, not staggered joins — `[testing] [realtime] [webrtc]`
- Keep `NgOptimizedImage` off runtime blob and data URLs — `[angular] [images]`
- Read the exact Obsidian bug note for `fix bug "…"` (one note only) — `[workflow] [bugs]`
- Run `npm run i18n:sync` after editing any `public/i18n/catalog/*.json` file — `[i18n] [testing]`
- Match direct-call recipients against every local identity alias, exactly like DMs already do — `[direct-call] [identity]`
- Resolve outbound direct-call recipient ids to the peer's connected signal identity — `[direct-call] [identity] [signaling]`
- Canonicalize direct conversation ids across cross-signal actor aliases — `[direct-message] [identity]`
- Decide attachment receive admission once at request time; never re-gate size in the chunk handler — `[attachments]`
- Re-queue attachment auto-downloads on every message/room binding event; never trust one transport's ordering — `[attachments] [realtime]`
- Scope per-user UI state by user id, not by the client database — `[persistence] [multi-user] [custom-emoji]`
@@ -57,4 +66,16 @@ Tags help grepping: `rg '\\[attachments\\]' agents-docs/LESSONS-INDEX.md`
- Prove the asked behavior; unit-green is not done — `[verification] [testing] [workflow]`
- Default to `toju-app/` + targeted `electron/` + CI; do not crawl the monorepo — `[workflow] [tokens] [scope]`
- Write/overwrite HANDOFF.md for new chats; clear it when the task finishes — `[workflow] [tokens] [handoff]`
- An outage test that only re-checks the end state is not a guard — `[testing] [verification] [webrtc]`
- coturn hands out a relay candidate but refuses loopback peers by default — `[testing] [webrtc] [turn]`
- Pin a chosen media device with `deviceId: { exact }`, never a bare string — `[webrtc] [media] [electron]`
- A second dev Electron window needs its own `--user-data-dir``[electron] [dev-shell]`
- Never answer `second-instance` by relaunching the app — `[electron] [dev-shell]`
- `ERR_FAILED (-2)` on a dev `loadURL` usually means aborted, not unreachable — `[electron] [dev-shell]`
- Never gate a presence indicator on the observer's own participation — `[ui] [voice] [webrtc]`
- Never test suspend/resume against a live-reloading dev server — `[testing] [dev-shell] [verification]`
- Keep diagnostic history outside the page you are diagnosing — `[testing] [verification]`
- Record whether the user is in a call before calling zero RTP a failure — `[testing] [voice] [verification]`
- Assert continuity when the state you broke repairs itself — `[testing] [voice] [verification]`
- Missing gossip about a peer is not evidence it left voice — `[voice] [webrtc] [realtime]`