telemouse v0.1.1
Hardening release from the September production-readiness audit: the
shipped config is loopback-only, the toolchain is pinned, the viz serves
only the overlay to other machines, and every run leaves its loss counters
next to the recording. Windows only, as before; recordings and the wire
format are unchanged and every older recording still loads.
- Release config split.
telemouse.example.toml(loopback everywhere,
Kafka off) is what the release zip now ships astelemouse.toml; the
repository'stelemouse.tomlis the development machine's own config and
no longer reaches a release with its LAN bind and broker addresses. - Network mode is overlay-only. When the viz is bound off loopback, a peer
that is not this machine is served/obs,/wsand/healthz; the
dashboard, the recording list and the recordings answer 403. Live
WebSocket clients are capped at 16, pinged every 20 s, and the sessions
listing is reused for 5 s, so a device on the LAN can no longer pin the
disk or a core by looping a request. Both servers addX-Frame-Options: DENY,X-Content-Type-Options: nosniffandReferrer-Policy: no-referrer. - Session metadata sidecar. The agent writes
recordings/<session>.meta.jsonwhen it stops — why it stopped, whether
every thread joined cleanly, event/drop totals, and per-sink errors,
drops and abandoned envelopes.telemouse-analyze listshows aLOSS
column and the JSON listing carrieslossesandexit, so a Kafka outage
that dropped batches is visible afterwards without reconciling the JSONL. - Config validation. Every
kafka.brokersentry must behost:port
(a port-less entry was silently unreachable).ctl.stop_grace_secs
defaults to 8 s, above the agent's two 3 s sink drains, so a slow disk or
broker at stop time delays the stop instead of truncating the recording. - Recording names follow one rule.
telemouse_core::recordings::is_safe_id
([A-Za-z0-9_-]) is now applied by the panel and the analyzer as well as
the viz; the panel's separator check alone let a drive-relative
C:x.jsonlresolve outside the recordings directory on Windows. - Failures are louder. Every binary installs a
tracingpanic hook; the
capture context thread has an alive guard (a panic there used to freeze the
game name for the rest of the session); viz/healthzanswers 503 with
udp_bound: falsewhile its listener is down and reports the seconds
since the last datagram; the panel explains anunknown fieldexit as a
binary older than the config and rotates component logs by size while it
runs, not only at startup. - Toolchain and CI.
rust-toolchain.tomlpins 1.98.0 for CI and
developers; clippy and fmt gate the release job too; every cargo step runs
--locked; the viz page's script is nowcrates/viz/src/app.js, inlined
at startup, syntax-checked withnode --checkin CI and in the test
suite, and unit-tested with Node against a stub DOM. - The raw-input buffer walk rounds each block up to the pointer size (the
NEXTRAWINPUTBLOCKrule) and bounds every block by the buffer. - Control panel: a system-wide new-session hotkey,
[ctl] hotkey(default
ctrl+alt+r), stops the capture agent if it is running and starts one that
saves — a fresh recording without leaving the game. The tray menu gains the
same New session item and shows the chord; a balloon confirms each press. - Performance/latency follow-up: 256 KiB replay streaming and direct recording
lookup make a 532 MB replay 7.9x faster; the live browser trims typed arrays
in chunks; capture/browser defaults are now 25/35 ms for a roughly 35 ms
live-display floor. - Analyzer: persistent change-sensitive recording metadata index, one timestamp
vector instead of two, bounded interval searches, and dependency-aware
scoped parallelism. On the 8-million-event audit recording, warm listing is
4,972 → 17–23 ms, per-minute aggregation is 83.7 → 42.5 ms, and report build
is 1,390 → 846 ms median with a 6.9% peak-memory increase. - Capture isolation: JSONL writes/one-second flushes and Kafka initialization
run on bounded workers. Slow storage and the five-second broker connection
timeout no longer stall the shipping loop or capture startup; queue/drop/
abandoned-work telemetry makes degradation explicit. Flush-confirmed JSONL
accounting and Kafka terminal-failure handling avoid silent loss counters
and repeated per-batch error allocation during an outage. - Viz aim panel: yaw is drawn unwrapped. Crossing ±180° no longer teleports
the head to the far edge (which made the camera pan and the zoom balloon);
the seam is a dashed line at every odd multiple of 180° and the origin axis
repeats every 360°. - Local Kafka broker:
compose.yamlruns a single-node KRaft Apache Kafka
3.9 on127.0.0.1:9092with persistent data;[kafka] enabledis now
truein the repotelemouse.toml. Capture still degrades to UDP +
JSONL with a warning when the broker is down. - OBS overlay from another PC: the repo
telemouse.tomlnow binds the viz
to0.0.0.0:7879so a streaming PC on the LAN can use
http://<gaming PC IP>:7879/obsas its Browser source; README and GUIDE
document the firewall rule and the IP-literal requirement. The control
panel's viz link and the viz's own startup line print a browsable
loopback URL when the bind is unspecified (0.0.0.0/[::]).