From 54780fa73b3a79df26dfe436cba496358f879d29 Mon Sep 17 00:00:00 2001 From: Mollusk Date: Thu, 18 Jun 2026 01:51:26 -0400 Subject: [PATCH] Remove Codex task-report.md from repo root Transient implementer handoff note; its content is preserved in the handoff docs. Not repo content. Co-Authored-By: Claude Opus 4.8 --- task-report.md | 81 -------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 task-report.md diff --git a/task-report.md b/task-report.md deleted file mode 100644 index daf9ef5..0000000 --- a/task-report.md +++ /dev/null @@ -1,81 +0,0 @@ -# Codex task report - 2026-06-16 - -## W2 - Per-peer EQ - -- Added `src/audio/eq.rs`: a 3-band listener-side RBJ biquad EQ (low shelf, mid peaking, high shelf) with per-peer state and flat bypass. -- Added local config persistence in `AppConfig.peer_eq`, keyed by peer node id string. -- Added local `CoreCommand::SetPeerEq` and mixer-side per-peer `Eq` state. EQ is applied after local volume and before pan/mix; raw multitrack stems remain pre-volume/pre-EQ. -- Added participant-card controls for Low/Mid/High gain sliders (-12 dB to +12 dB). Changes apply live and persist on slider release. -- Tests added for flat identity, low/high boost energy, coefficient finiteness, clamping, and hot-signal processing. - -Unverified: subjective voice quality and zipper/noise behavior on real devices. - -## W1 - Per-listener pan / stereo playback - -- Added `src/audio/pan.rs`: constant-power `pan_gains()` with tests, plus playback gains that preserve the legacy default dual-mono center. -- Converted playback mix to interleaved stereo in `src/core/mod.rs`. -- Switched PipeWire playback output to 2-channel S16LE and adjusted ring target/capacity/stride accounting in `src/audio/pipewire_impl.rs`. -- Kept capture, Opus encode/decode, jitter buffers, and network audio mono. -- Limiter now receives the interleaved stereo bus; shared limiter gain ducks both channels consistently. -- Mixed WAV and multitrack convenience mix fold the listener stereo mix back to mono before writing. Per-peer stems remain raw mono. -- Updated `audio_probe` to send dual-mono stereo frames. -- Added tests for exact center dual-mono behavior, hard-left pan contribution, and stereo fold-down. - -Decision for senior sanity-check: pure pan law is constant-power, but playback scales it by sqrt(2) so pan=0 is exactly the old mono signal in both ears. This satisfies the "default behavior unchanged" guardrail at the cost of louder hard-panned extremes, which the existing limiter catches. - -Unverified: real PipeWire stereo playback, underrun behavior on actual hardware, and recorded WAV listening checks. - -## W5 - Focused hotkeys + info popup - -- Added `src/hotkeys.rs`: serializable `KeyBinding`, `HotkeyAction`, `HotkeyMap`, parse/format/lookup, tier checks, and duplicate conflict detection. -- Added `AppConfig.hotkeys` with defaults: F9 mute, F10 deafen, F2 Settings, Space push-to-talk, Leave unset. -- Replaced the hard-coded PTT key capture with config-backed binding capture. -- Added Settings hotkey editor with Set/Clear per action and live conflict warnings. -- Added top-right hotkey info popup that lists every action and current binding, showing `unset` for unbound actions. -- Routed focused iced key events through the map. App-wide actions can fire from any screen while focused; room-only actions require an active call. PTT press/release still uses `SetPttActive`. -- Tests added for unset formatting, duplicate detection, room-tier lookup, defaults, and character parse/format. - -Unverified: manual keyboard interaction in the GUI. No OS-global hooks were added. - -## W3 - PipeWire pro-routing plan (not implemented) - -I stopped at design for W3. The current backend already supports simple target-node routing through PipeWire stream property `node.target`, but true "pro routing" (explicit ports / manual graph links / no-autoconnect patching) would require backend changes that are not safely verifiable offline. - -Proposed future scope: - -- Expose two advanced route targets: capture source node and playback sink node, with optional future per-port routing. -- Enumerate available nodes with the existing `pw-cli list-objects Node` parser. For port-level routing, add a separate parser for `pw-cli list-objects Port` collecting `object.id`, `node.id`, `port.name`, direction, and channel position. -- For node-level routing, continue using PipeWire stream property `node.target` on stream creation. This is the low-risk path and matches current backend behavior. -- For explicit port routing, do not use `AUTOCONNECT`; instead capture the created PeerSpeak stream node/port ids from the PipeWire registry, then link with PipeWire-native APIs or `pw-link `. Degrade by falling back to `node.target` autoconnect if any selected node/port is missing. -- Offline tests should cover pure routing-plan decisions: selected node exists/missing, selected port exists/missing, capture/playback direction mismatch, and fallback choice. Real-device tests still need a PipeWire graph. - -Reason for not implementing: the current `run_playback` / `run_capture` code does not retain stream node or port ids, and changing `AUTOCONNECT` behavior plus adding manual `pw-link` calls could destabilize the working audio path. That matches the assignment's "bail if risky" instruction. - -## Backlog A21/A22 - correctness fixes - -- Fixed A21 in `src/core/jitter.rs`: implausibly large sequence discontinuities now reset the per-peer jitter stream instead of being treated as ordinary late packets or packet loss. -- The reset threshold is `500` frames, about 10 seconds at 20 ms/frame. That covers both same-identity sender restart back to sequence 0 and a faulty/malicious jump far ahead that would otherwise force a long PLC run. -- Added jitter regression tests for both far-behind restart and far-ahead jump cases. -- Fixed A22 in `src/audio/recorder.rs`: `WavWriter` now tracks data bytes as `u64`, checks additions before writing, and rejects data that cannot fit both the RIFF size field and the `data` chunk size field. -- Added a WAV overflow regression test that exercises the limit without creating a huge file. - -Unverified: the same-identity peer restart has not been exercised in a live 2-machine call; the WAV fix is counter/size-field tested, not a real >12h recording. - -## Backlog A14 - orderly window-close shutdown - -- Added `CoreCommand::Shutdown` and `UiEvent::ShutdownComplete`. -- Window close now saves config, marks the GUI as closing, asynchronously queues `Shutdown`, and exits only after the core acknowledges completion or after a 5-second fallback timeout. -- Core shutdown finalizes active mixed/multitrack recordings before session teardown, stops the standalone mic monitor, runs `ActiveSession::shutdown()` for active calls, clears room presence/routing, closes the persistent network stack, sends `ShutdownComplete`, and ends the core loop. -- The shutdown command is queued with an awaited `mpsc::Sender::send` task instead of the best-effort `try_send`, so a full command queue does not immediately drop the close command. - -Unverified: actual GUI window-close behavior during a live call/recording still needs a manual run; tests/builds only prove the path compiles and existing unit coverage still passes. - -## Verification - -- `cargo check` passed. -- `cargo test --lib` passed: 288 passed, 0 failed, 2 ignored. -- `cargo clippy --all-targets` passed. -- `cargo build --release` passed. -- Formatted the touched Rust files with `rustfmt --edition 2024`; I did not run repo-wide `cargo fmt` to avoid unrelated formatting churn. - -No new dependencies were added. Runtime/manual/field verification is still pending for audio-device and 2-machine behavior.