The native viewer's H.264 path (Task 7 first-cut, compile-verified only)
never rendered a frame. Three stacked bugs, all confirmed via live loopback:
1. decoder: MF_E_NOTACCEPTING (0xC00D36B5) was treated as fatal and only
one output was drained per call, so once the MFT filled it rejected
every subsequent frame. decode() now returns Vec<DecodedFrame>, drains
on back-pressure and retries the unconsumed sample, then drains all
ready outputs.
2. decoder: the NV12 output type was hand-built and rejected by the MS
H.264 decoder MFT (MF_E_TRANSFORM_TYPE_NOT_SET, 0xC00D6D60). It is now
negotiated by enumerating GetOutputAvailableType on STREAM_CHANGE /
TYPE_NOT_SET.
3. render: a manual pump_messages() in about_to_wait stole winit's own
thread messages and froze the event loop after one iteration, so frames
were never drained from the channel. Removed; winit's run_app pump
already services the WH_KEYBOARD_LL hook.
Validated on a 5070 loopback: 0 decode errors, frames decode/paint/present
(present count 0 -> 1740). Reviewed (APPROVE-WITH-NITS); diagnostics stripped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SPEC-002 Phase 1 Task 6, code-reviewed APPROVED (2 rounds), locally verified
(cargo fmt + clippy -D warnings exit 0 + cargo test --workspace 70 pass + build).
- Viewer WH_KEYBOARD_LL hook diverts system combos (Win/Win+R, Alt+Tab, Alt+Esc,
Ctrl+Esc) to the remote as a full KeyEvent (vk + scan + is_extended + modifiers)
and suppresses local handling - GATED on the viewer window having focus AND a
"send system keys" toggle (default on; Pause/Break host-key), so it never bricks
the technician's local keyboard when unfocused.
- Agent injection via SendInput KEYEVENTF_SCANCODE + correct KEYEVENTF_EXTENDEDKEY
(right Ctrl/Alt, arrows, nav, Win, NumLock, numpad Divide) - layout-independent,
extended-key-correct.
- Ctrl+Alt+Del completes through the SAS helper (SYSTEM SendSAS); installer sets
the SoftwareSASGeneration policy; 3-tier fail-loud (no false success). SAS named
pipe DACL tightened from NULL/Everyone to Authenticated Users.
- Modifier hygiene: viewer emits key-ups for held Ctrl/Alt/Shift/Win on focus loss
/ close so modifiers never stick on the remote.
- proto: KeyEvent.is_extended = 7 (additive; older agents derive the flag).
Closes Win+R / Ctrl+C-V / Ctrl+Alt+Del / arrows-vs-numpad fidelity. Live on-device
testing is plan Task 8.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI never ran clippy on the agent crate (the build-server clippy job is
Linux-only and can't compile the Windows agent; build-agent only runs cargo
build), so 77 clippy -D-warnings errors had accumulated. Behavior-preserving
cleanup, code-reviewed APPROVED, locally verified (cargo clippy --workspace
--all-targets --all-features -- -D warnings exits 0; cargo test --workspace =
57 passed).
- let _ = on Win32 resource-teardown BOOL returns (gdi.rs); fallible
BitBlt/GetDIBits stay error-handled
- removed unused imports/vars; idiom fixes (div_ceil, is_null, transmute
annotations, match collapsing, useless_conversion)
- #[allow(dead_code)] + comment on genuine Task-6/7 scaffolding (vk consts,
SpecialKey emission, SAS mgmt API, modifier tracking, GDI frame-diff fields)
- Cargo.lock: cargo pruned ~147 stale transitive entries (no version changes)
Follow-up: add cargo clippy -D warnings to the build-agent CI job so the agent
crate stays clippy-clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First run of the build-and-test CI gate (cargo fmt --all -- --check) surfaced
pre-existing formatting drift across the agent and server crates. Apply rustfmt
across the workspace so the codebase meets its own CI gate. Pure formatting; no
logic changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>