Layered test coverage for the Windows PTT subsystem ahead of the
v1.0.0-rc.8 official release sign-off.
L0 (refactor)
- Extract three pure-logic dispatchers from the existing WndProc /
LowLevelKeyboardProc / LowLevelMouseProc bodies in
crates/chanora_audio/src/ptt_backends/windows.rs:
dispatch_raw_input(ctx, &RAWINPUT)
dispatch_hook_keyboard(ctx, wparam, &KBDLLHOOKSTRUCT)
dispatch_hook_mouse(ctx, wparam, &MSLLHOOKSTRUCT)
Each takes a small Context (AtomicBinding + AudioTransmitGate +
flags) and is callable without spinning up any Win32 plumbing.
The real Win32 procs unchanged structurally; they unpack lparam
and forward to the dispatchers. AtomicBinding / RawInputContext
/ HookContext / resolve_binding are now pub(crate) so the
in-file test module can drive them.
L1 — windows_keymap full-table sweep (+13 tests)
Every key_label_to_vk arm, all A-Z + a-z, all 0-9, F1-F20,
navigation, modifiers, OEM punctuation, numpad. Exhaustive
mouse_label_to_button cases including the 0x08 / 0x10 /
unknown-bitmask fallbacks.
L2 — AtomicBinding lock-free correctness
store/read round-trip, clear(), Default = zeros, single-writer
/ single-reader concurrency, many-readers / single-writer.
L3 — resolve_binding dispatcher tests
All PttInputClass variants, well-known labels, unknown-label
fallback, mismatched class+label rejection, mouse bitmask
resolution.
L4 — Backend state-machine
Both WindowsRawInputBackend and WindowsHookBackend:
descriptor() pre-arm vs post-arm (L0Focused -> L2/L3), start()
with None binding rejection, rebind() in-place, stop()
clears + idempotent, stop() after stop() no-op.
L5 — dispatch_raw_input table
Keyboard match/non-match, key-down/key-up via Flags & 0x01,
no-binding short-circuit, mouse XBUTTON1/XBUTTON2 down/up
matching the bound button, unhandled HID type. RAWINPUT structs
built via mem::zeroed plus field-fill, owning the unsafe in
the test layer where it belongs.
L6 — dispatch_hook_keyboard + dispatch_hook_mouse
WM_KEYDOWN / WM_KEYUP / WM_SYSKEYDOWN / WM_SYSKEYUP for the
keyboard path, WM_XBUTTONDOWN / WM_XBUTTONUP for the mouse
path. Same shape as L5.
L7 — Privacy invariant (crates/chanora_audio/tests/ptt_privacy.rs)
New cross-platform integration test installs a custom
tracing_subscriber Layer that records every emitted event's
target + field names. Exercises the public PTT API plus (on
Windows) the backend factory. Asserts no field name in the
banned list (vk, scan_code, keysym, key_label, bound_key,
binding, platform_key, VKey, wVk, wScan, kbflags, mouseflags)
is ever emitted and every field belongs to the DEC-027
allow-list. Adds tracing-subscriber as a dev-dependency on
chanora_audio.
L8 — Full-chain integration in core/chanora_core/src/ptt.rs
Windows-only mod windows_full_chain_tests:
zero-tail full chain (synchronous)
default-tail full chain (200 ms wait then off)
mid-press rebind abandons in-flight press
L9/L10/L11 — tools/windows-smoke.cmd + tools/windows-smoke.md
Batch smoke script + operator doc. cargo build, flutter build,
artifact existence + size checks, headless launch with stderr
capture, bridge-initialised log assertion. Distinct exit codes
per failure step. Doc explains invocation + common failure
modes.
Verification (Linux)
- cargo check --workspace: clean.
- cargo test --workspace: 78 passed / 0 failed / 3 ignored.
76 cross-platform unit tests (unchanged) plus the new
ptt_privacy integration test plus one new ignored portal smoke
test.
The Windows-gated tests (~49 new) compile and run on the Korean
Windows 11 host where they belong; cross-compile from Linux is
not configured locally. The smoke script is the production
acceptance gate for rc.8 on Windows.
Deviations from the original plan are minor (single ignored
real-runtime test rather than per-platform attribute, L7 uses
public API rather than pub(crate) dispatchers, dispatchers live
inside windows.rs rather than a sibling module) and documented
in the subagent report.
3.8 KiB
3.8 KiB
tools/windows-smoke.cmd — Korean host smoke build + launch
End-to-end "does Chanora build and start on Windows" verification.
Designed for the lead's Korean Windows 11 test host and the
product/scaffold-v0 branch. Run from any directory inside the
checked-out repo:
C:\Users\admin\chanora> tools\windows-smoke.cmd
The script pushd's to the repo root (resolved from its own
location), so the working directory does not matter as long as
the script lives in tools\ inside the checkout.
What it does
- Prepends Flutter + Cargo + MSVC to
PATHand runsvcvars64.bat. Hard-coded paths assume the Korean host layout. If a path changes, edit theset "PATH=..."andcall "...\vcvars64.bat"lines near the top. cargo build -p chanora_bridge --releaseand checkstarget\release\chanora_bridge.dllexists and is at least 5 MB.flutter build windows --releaseinsideapps\chanora_flutterand checks the runner +data\app.so.- Copies the bridge DLL into the Flutter release folder.
- Launches the runner for five seconds with stderr redirected to
%TEMP%\chanora-smoke.log, then kills it. - Greps the log for
bridge initialised(must be present) andpanicked(must be absent). - Prints
PASSand exits 0 on success.
Exit codes
| Code | Step |
|---|---|
| 0 | PASS |
| 1 | vcvars64.bat failed |
| 2 | cargo build -p chanora_bridge --release failed |
| 3 | bridge DLL missing or smaller than 5 MB |
| 4 | flutter build windows --release failed |
| 5 | chanora_flutter.exe missing |
| 6 | data\app.so missing or smaller than 1 MB |
| 7 | bridge DLL copy into the Release folder failed |
| 9 | log did not contain bridge initialised (bridge didn't load / panic at init) |
| 10 | log contained panicked (Rust panic during the 5 s smoke window) |
Common failure modes
- vcvars64 returns non-zero: MSVC not installed at the
expected path. Update the
call "...\vcvars64.bat"line or install the Build Tools workload from the VS2022 installer. cargo buildfails withlink.exe not found: vcvars64 did not take effect. Re-run from a freshcmd.exe(PowerShell has its own quirks here).- Bridge DLL exists but smaller than 5 MB: a debug build
slipped in. Make sure the script's
--releaseflag was honoured; check that no[profile.release]override is stripping symbols too aggressively. data\app.sosmaller than 1 MB: Flutter assets did not bundle. Runflutter cleanthen re-run the script.bridge initialisedabsent: the bridgeexternsymbol is not being found by the Flutter side. Verify the DLL copy step ran (it did, or the script would have exited 7) and that the DLL name matches whatlib/main.dart's ffi setup expects.panickedpresent: open%TEMP%\chanora-smoke.log(the script dumps it on failure) and read the panic message. The most common cause during scaffold development is a missing flutter-rust-bridge code-gen file; re-run the codegen step perdocs/release/desktop-build-runbook.md.
Manual rerun of just the launch step
The PASS path always tears the runner down. If you want to inspect the running application after a green smoke pass:
target\release\chanora_bridge.dll (already copied into Release\)
apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe
Launching the EXE directly will reuse the copied DLL.