Update docs
This commit is contained in:
83
PROGRESS.md
83
PROGRESS.md
@@ -53,7 +53,14 @@ up instantly. Newest status at the top.
|
||||
(mutex lock, heap allocation, blocking `sendto` on the miniaudio real-time callback
|
||||
thread) — predates this work, documented but not fixed; fixing it needs the lock-free
|
||||
ring-buffer hand-off `docs/architecture.md §3` specifies, a separate, larger refactor.
|
||||
- **Next:** **M4 — native clients** (Windows C#, macOS/iOS Swift). See `docs/roadmap.md §M4`.
|
||||
- **Done:** **M4 — Windows WinForms C# client** ✓ complete (2026-06-17). Full details in the
|
||||
M4 section below. `ctest --preset m1-dev` — **14/14 tests** green. `dotnet build` — 0
|
||||
warnings/errors across all three C# projects. Manually verified: saved servers, TOFU
|
||||
first-connect dialog, channel tree, join, voice (VAD/PTT/always-on + sensitivity slider +
|
||||
per-user gain/mute/NR), text chat (channel + private), device pickers, level meter.
|
||||
- **Next:** macOS/iOS Swift client (M4 continued) and/or **M5** (admin UI, moderation, kick/
|
||||
ban). The C ABI is complete and stable through M4 — both directions are unblocked. See
|
||||
`docs/roadmap.md §M4–M5`.
|
||||
|
||||
---
|
||||
|
||||
@@ -63,7 +70,7 @@ up instantly. Newest status at the top.
|
||||
- [x] **M1 — Control plane** ✓ complete (2026-06-15)
|
||||
- [x] **M2 — Voice, single stream** ✓ complete (2026-06-16)
|
||||
- [x] **M3 — Multi-stream & per-channel tuning** ✓ complete (2026-06-16)
|
||||
- [ ] **M4 — Native clients** (Windows C#, macOS/iOS Swift) ← next
|
||||
- [~] **M4 — Native clients** — Windows WinForms ✓ (2026-06-17); macOS/iOS Swift pending
|
||||
- [ ] **M5 — Moderation, polish, beyond** (perms, bans, DRED; then file transfer, E2EE, …)
|
||||
|
||||
---
|
||||
@@ -349,6 +356,78 @@ flags), and `vccli --voice --input-mode vad` connecting + streaming without inci
|
||||
|
||||
---
|
||||
|
||||
## M4 — Windows WinForms C# client ✓ (completed 2026-06-17)
|
||||
|
||||
**Exit criterion:** ✓ `ctest --preset m1-dev` — **14/14 tests** green (existing 12 + 2 new
|
||||
C++ tests: `test_channel_user_list_abi`, `test_tofu_flow`). `dotnet build` — 0 warnings/errors.
|
||||
Manually verified: connect, TOFU first-connect dialog, channel tree, join, voice, text, device
|
||||
pickers, level meter. Accessibility: explicit `AccessibleName`/`AccessibleDescription` on every
|
||||
control, `&` mnemonics on every button, activity-log `ListBox` as screen-reader record.
|
||||
|
||||
**New C++ ABI surface** (all additive, backward-compatible):
|
||||
- `vc_list_channels` / `vc_list_users` / `vc_list_user_streams` — pull-based snapshot getters
|
||||
for the channel tree + user list; `session_model_mu_` added for cross-thread safety.
|
||||
`SessionModel::apply_snapshot`/`apply_channel_event` fixed to populate `parent_id`,
|
||||
`password_protected`, `max_users` (were permanently zeroed despite the struct declaring them).
|
||||
- `vc_join_channel(channel_id, password)` — join with optional password; server replies via
|
||||
new `VC_EVENT_JOIN_RESULT`.
|
||||
- `VC_EVENT_SERVER_IDENTITY` + `vc_confirm_server_identity(accept)` — TOFU gate that blocks
|
||||
`io_thread_` until the UI approves or rejects. Pins the TLS leaf-cert SHA-256 fingerprint
|
||||
(verifiable directly at handshake), **not** the declared Ed25519 value (see docs/security.md
|
||||
§1.1 for why — the TLS cert and Ed25519 key are generated independently, no binding).
|
||||
`vc_get_server_identity_display` exposes the Ed25519 fingerprint for human-readable display.
|
||||
- `vc_config::tofu_store_path` — optional per-user pin file path; defaults to a relative
|
||||
`"./voicecat_tofu_pins.txt"` so existing tests need no change.
|
||||
- `TcpAcceptor` now dual-stacks (IPv6 + IPv4 fallback) so `localhost` → `::1` on Windows
|
||||
connects correctly without forcing users to type `127.0.0.1`.
|
||||
- `VC_INPUT_ALWAYS_ON = 2` in `vc_input_mode` — transmit unconditionally (no VAD gate).
|
||||
- `vc_set_vad_threshold(float)` — live VAD threshold update; `EnergyVadProcessor` stores it
|
||||
atomically so the RT capture path reads without a lock or allocation.
|
||||
|
||||
**New C++ tests:**
|
||||
- `test_channel_user_list_abi` — snapshot getters, `parent_id`/`password_protected`/`max_users`
|
||||
regression, per-user stream list, invalid-user-id error, double-free idempotency.
|
||||
- `test_tofu_flow` — first-connect blocks until confirmed; reject doesn't persist; reconnect to
|
||||
same identity reports `MATCHED`; rotated identity reports `MISMATCH`; `vc_confirm_*` with
|
||||
nothing pending returns an error.
|
||||
|
||||
**`windows-client` CMake preset** — Release, `VOICECAT_BUILD_SHARED=ON`, static MinGW runtime
|
||||
(`-static-libgcc -static-libstdc++ -static -lwinpthread`), no tools/tests. Outputs
|
||||
`build/windows-client/bin/voicecat.dll` with zero MinGW DLL dependencies (only Windows system
|
||||
DLLs remain — verified via `objdump -p`).
|
||||
|
||||
**C# solution** (`clients/windows/`, .NET 10 LTS `net10.0-windows`):
|
||||
- `VoiceCat.Interop` — `[LibraryImport]` P/Invoke surface, `[UnmanagedCallersOnly]` callbacks,
|
||||
`System.Threading.Channels.Channel<VoiceCatEvent>` event delivery drained by 30ms WinForms
|
||||
Timer; `VoiceCatClientHandle : SafeHandle` guarantees `vc_client_destroy`.
|
||||
- `VoiceCat.App` — WinForms UI:
|
||||
- `ConnectDialog` — saved-server `ListBox`, Add/Remove/Edit; servers persisted to
|
||||
`%AppData%\VoiceCat\servers.json`; passwords DPAPI-encrypted (`ProtectedData`, opt-in).
|
||||
- `ServerIdentityDialog` — shown only on `FIRST_CONNECT`/`MISMATCH` (never `MATCHED`);
|
||||
mismatch text and button ordering are starkly different ("WARNING" framing, Cancel default).
|
||||
- `MainForm` — `TreeView` channel tree, `ListBox` user list, `RichTextBox` chat, scope
|
||||
`ComboBox` (Channel/Private), activity-log `ListBox`, voice panel with mic toggle,
|
||||
mute/deafen checkboxes, VAD/PTT/Always-On radio group, VAD sensitivity `TrackBar`
|
||||
(1–100, hidden for non-VAD modes), device `ComboBox` + refresh, level `ProgressBar`.
|
||||
- `PerUserTuningDialog` — real-time gain `TrackBar` + mute/NR checkboxes; applied to all
|
||||
of a user's streams immediately (no OK/Cancel round-trip).
|
||||
- `PttKeyCaptureDialog` — focus-scoped PTT key capture.
|
||||
- `VoiceCat.Interop.Tests` — xunit smoke test: connect → TOFU → guest auth → list channels
|
||||
purely via P/Invoke against a live `voicecat-server.exe`.
|
||||
|
||||
**Explicitly out of scope for this pass:**
|
||||
- macOS/iOS Swift client — pending.
|
||||
- Admin/moderation UI (kick/ban/permissions/account provisioning) — server-side dispatch for
|
||||
these messages is M5's job; building the UI now would require building the server side too.
|
||||
- PTT hotkey is **focus-scoped only** (works while VoiceCat window has focus). A system-wide
|
||||
`WH_KEYBOARD_LL` hook would require escalated permissions and risk AV flagging — documented
|
||||
limitation, not silently omitted.
|
||||
- Receive-side noise reduction (`vc_set_remote_stream(..., noise_reduction)`) is end-to-end
|
||||
plumbed but behaviorally a passthrough no-op (`ApmPassthrough`, no PCM modification) —
|
||||
same as before M4. The per-user NR checkbox in `PerUserTuningDialog` is labeled accordingly.
|
||||
|
||||
---
|
||||
|
||||
## Decisions log
|
||||
|
||||
All architecture/scope decisions are settled and recorded in
|
||||
|
||||
Reference in New Issue
Block a user