@codexstar/pi-listen 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,613 @@
1
+ # pi-voice technical remediation plan
2
+
3
+ ## Goal
4
+
5
+ Turn `pi-voice` into a technically robust package that can support a premium onboarding flow without accumulating more correctness debt. This plan focuses on the architecture behind onboarding, runtime correctness, dependency provisioning, backend metadata, portability, and package structure.
6
+
7
+ ## Current technical issues
8
+
9
+ ### 1. Config is too thin
10
+ The current config model only captures:
11
+
12
+ ```json
13
+ {
14
+ "voice": {
15
+ "enabled": true,
16
+ "language": "en",
17
+ "backend": "auto",
18
+ "model": "small"
19
+ }
20
+ }
21
+ ```
22
+
23
+ That is not enough to represent:
24
+ - whether onboarding was completed
25
+ - whether the user chose cloud vs local intentionally
26
+ - which scope owns the config (global vs project)
27
+ - whether auto-install is allowed
28
+ - whether the backend was validated successfully
29
+ - which daemon/runtime profile should be active
30
+
31
+ ### 2. Global daemon state can drift from config
32
+ Today the extension uses one hard-coded socket path:
33
+ - `extensions/voice.ts` -> `SOCKET_PATH`
34
+ - `daemon.py` -> `DEFAULT_SOCKET`
35
+
36
+ That creates shared mutable state across:
37
+ - projects
38
+ - sessions
39
+ - potentially different backend/model selections
40
+
41
+ `ensureDaemon()` returns early if any daemon is already running, even if that daemon was started with a different backend/model. `transcribeAudio()` currently does not pass `backend` and `model` to the daemon request, so the active daemon can silently continue with stale settings.
42
+
43
+ ### 3. Setup persistence is inconsistent
44
+ `loadConfig()` merges global and project settings, but `/voice setup` writes only to global settings. That means the package already behaves as if scoped config matters, but it cannot save project-level intent.
45
+
46
+ ### 4. Backend metadata is insufficient for recommendation and provisioning
47
+ `transcribe.py` exposes:
48
+ - `name`
49
+ - `available`
50
+ - `type`
51
+ - `default_model`
52
+ - `install`
53
+ - `models`
54
+
55
+ That is enough for a raw picker, but not for a recommendation engine or enterprise onboarding. The package lacks structured metadata for:
56
+ - privacy posture
57
+ - network requirement
58
+ - expected latency
59
+ - expected disk use
60
+ - install complexity
61
+ - whether warm model caching is supported
62
+ - whether the backend can be auto-installed safely
63
+ - recommended hardware tier
64
+
65
+ ### 5. No provisioning abstraction exists
66
+ Installation and dependency repair are currently implicit/manual. There is no dedicated subsystem for:
67
+ - checking prerequisites
68
+ - producing an install plan
69
+ - executing safe install actions
70
+ - collecting stdout/stderr
71
+ - classifying failure modes
72
+ - retrying or falling back
73
+
74
+ ### 6. Package shape is too minimal
75
+ The package is technically valid, but not operationally mature. It lacks:
76
+ - docs in the publish list
77
+ - scripts for validation
78
+ - package metadata for discoverability/supportability
79
+ - a modular code layout that can safely absorb onboarding and diagnostics growth
80
+
81
+ ## Technical design principles
82
+
83
+ 1. **Config is explicit, versioned, and migratable.**
84
+ 2. **Runtime profile selection must be deterministic.** The active daemon must always match saved intent.
85
+ 3. **Onboarding state is first-class.** “Not configured”, “configured”, and “broken” must be distinct states.
86
+ 4. **Backend metadata must drive both UX and install logic.**
87
+ 5. **Provisioning must be declarative first, imperative second.** Build an install plan before executing commands.
88
+ 6. **Project-local and global scope must both be supported cleanly.**
89
+ 7. **Non-interactive and interactive modes must degrade safely.**
90
+ 8. **Package structure should be modular before adding more product surface.**
91
+
92
+ ## Target architecture
93
+
94
+ ## 1. Versioned config model
95
+
96
+ Replace the flat config with a versioned schema.
97
+
98
+ ### Proposed shape
99
+
100
+ ```json
101
+ {
102
+ "voice": {
103
+ "version": 2,
104
+ "enabled": true,
105
+ "mode": "local",
106
+ "language": "en",
107
+ "backend": "faster-whisper",
108
+ "model": "small",
109
+ "scope": "global",
110
+ "hotkeys": {
111
+ "editorHoldToTalk": true,
112
+ "toggleShortcut": "ctrl+shift+v",
113
+ "btwShortcut": "ctrl+shift+b"
114
+ },
115
+ "runtime": {
116
+ "warmDaemonOnStart": true,
117
+ "vadEnabled": true,
118
+ "daemonProfile": "global-local-faster-whisper-small-en"
119
+ },
120
+ "onboarding": {
121
+ "state": "completed",
122
+ "schemaVersion": 2,
123
+ "source": "first-run",
124
+ "completedAt": "2026-03-12T00:00:00.000Z",
125
+ "lastValidatedAt": "2026-03-12T00:02:00.000Z",
126
+ "dismissedAt": null
127
+ },
128
+ "provisioning": {
129
+ "autoInstall": true,
130
+ "allowBrew": true,
131
+ "allowPipUser": true,
132
+ "lastPlanId": "install-plan-123"
133
+ },
134
+ "cloud": {
135
+ "provider": null,
136
+ "apiKeyEnv": null
137
+ },
138
+ "health": {
139
+ "status": "ready",
140
+ "lastError": null,
141
+ "lastBackendCheckAt": "2026-03-12T00:01:00.000Z"
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### Required config helpers
148
+
149
+ Create a dedicated config module with:
150
+ - `loadVoiceConfig(cwd)`
151
+ - `saveVoiceConfig(config, scope, cwd)`
152
+ - `migrateVoiceConfig(input)`
153
+ - `getVoiceSettingsPaths(cwd)`
154
+ - `resolveEffectiveConfig(globalConfig, projectConfig)`
155
+ - `getConfigOwnership(config)`
156
+
157
+ ### Scope model
158
+
159
+ Support both:
160
+ - global: `~/.pi/agent/settings.json`
161
+ - project: `<cwd>/.pi/settings.json`
162
+
163
+ Save path must be explicit, not implied.
164
+
165
+ ## 2. Onboarding state machine
166
+
167
+ Treat onboarding as a state machine, not a boolean.
168
+
169
+ ### Proposed states
170
+ - `unconfigured`
171
+ - `recommended`
172
+ - `provisioning`
173
+ - `validation_pending`
174
+ - `completed`
175
+ - `degraded`
176
+ - `dismissed`
177
+
178
+ ### Why this matters
179
+ This separates:
180
+ - first install
181
+ - partially configured local install
182
+ - failed cloud auth
183
+ - a previously good setup that later broke
184
+
185
+ ### Trigger logic on `session_start`
186
+
187
+ 1. Load and migrate config.
188
+ 2. If no UI, skip onboarding and runtime prompts.
189
+ 3. If state is `completed` and health is `ready`, proceed.
190
+ 4. If state is `unconfigured` or `degraded`, launch guided setup or show repair CTA.
191
+ 5. Only start the daemon after the config has been validated for the active runtime profile.
192
+
193
+ ## 3. Backend catalog abstraction
194
+
195
+ Move backend registry concerns out of ad-hoc strings and into a structured catalog consumable by both TypeScript and Python.
196
+
197
+ ### Proposed backend metadata fields
198
+
199
+ For each backend, expose:
200
+ - `id`
201
+ - `label`
202
+ - `mode` (`local` or `cloud`)
203
+ - `available`
204
+ - `warmModelCapable`
205
+ - `installMethod` (`pip`, `brew`, `env`, `manual`, `mixed`)
206
+ - `installCommands`
207
+ - `models`
208
+ - `defaultModel`
209
+ - `recommendedModelByProfile`
210
+ - `privacy` (`offline`, `cloud`, `hybrid`)
211
+ - `networkRequired`
212
+ - `resourceTier` (`low`, `medium`, `high`)
213
+ - `latencyTier` (`fast`, `balanced`, `slow`)
214
+ - `qualityTier` (`good`, `better`, `best`)
215
+ - `diskEstimate`
216
+ - `hardwareNotes`
217
+ - `apiKeyEnv`
218
+ - `validationStrategy`
219
+ - `autoInstallSupported`
220
+
221
+ ### Implementation options
222
+
223
+ Preferred:
224
+ - Add a shared `backends.json` or `backends.ts` manifest at the package level.
225
+ - Keep Python and TypeScript aligned by generating one side from the other, or by treating JSON as the source of truth.
226
+
227
+ Minimum acceptable:
228
+ - keep the Python registry but enrich `--list-backends` output with structured fields
229
+ - consume that richer JSON from the extension
230
+
231
+ ## 4. Diagnostics engine
232
+
233
+ Add a diagnostics subsystem that produces a machine-readable readiness report.
234
+
235
+ ### Inputs
236
+ - platform / architecture
237
+ - `python3` availability
238
+ - `brew` availability
239
+ - `rec` / SoX availability
240
+ - backend availability from `transcribe.py --list-backends`
241
+ - required env vars
242
+ - optional daemon status
243
+ - optional sample audio validation
244
+
245
+ ### Output shape
246
+
247
+ ```json
248
+ {
249
+ "status": "ready",
250
+ "recommendedMode": "local",
251
+ "recommendedBackend": "faster-whisper",
252
+ "recommendedModel": "small",
253
+ "issues": [
254
+ {
255
+ "id": "missing-sox",
256
+ "severity": "blocking",
257
+ "message": "SoX is required for microphone recording.",
258
+ "fix": {
259
+ "auto": true,
260
+ "commands": ["brew install sox"]
261
+ }
262
+ }
263
+ ],
264
+ "capabilities": {
265
+ "python": true,
266
+ "brew": true,
267
+ "rec": false,
268
+ "cloudAuth": false
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### Responsibilities
274
+ - recommend mode/backend/model
275
+ - classify blockers vs warnings
276
+ - provide install plans
277
+ - power `/voice doctor`
278
+ - feed onboarding defaults
279
+
280
+ ## 5. Provisioning subsystem
281
+
282
+ Create a dedicated provisioning layer instead of embedding installation logic inside command handlers.
283
+
284
+ ### New module responsibilities
285
+ - build install plan from diagnostics
286
+ - execute allowed steps
287
+ - stream progress and capture logs
288
+ - classify failures
289
+ - emit structured result objects
290
+
291
+ ### Proposed install action model
292
+
293
+ ```ts
294
+ interface InstallAction {
295
+ id: string;
296
+ type: "brew" | "pip" | "env-check" | "python-import" | "warm-model" | "validate-cloud";
297
+ label: string;
298
+ command?: string[];
299
+ safeToAutoRun: boolean;
300
+ retryable: boolean;
301
+ }
302
+ ```
303
+
304
+ ### Local provisioning flows
305
+ - install SoX if missing
306
+ - install backend runtime if supported
307
+ - optionally warm the selected model
308
+ - verify transcription path
309
+
310
+ ### Cloud provisioning flows
311
+ - verify required env var exists
312
+ - optionally validate API access with a lightweight provider request
313
+ - verify selected model is accepted
314
+
315
+ ### Failure handling
316
+ Each failed step should produce:
317
+ - step id
318
+ - command
319
+ - exit code
320
+ - stderr excerpt
321
+ - recommended remediation
322
+
323
+ That should be stored in memory during onboarding and surfaced by `/voice doctor`.
324
+
325
+ ## 6. Deterministic daemon lifecycle
326
+
327
+ This is the most important runtime fix.
328
+
329
+ ### Current problem
330
+ A global daemon can continue using a stale backend/model because the extension does not fully bind requests to the desired config.
331
+
332
+ ### Required design change
333
+ Introduce a `RuntimeProfile` abstraction.
334
+
335
+ ```ts
336
+ interface RuntimeProfile {
337
+ mode: "local" | "cloud" | "auto";
338
+ backend: string;
339
+ model: string;
340
+ language: string;
341
+ vadEnabled: boolean;
342
+ scope: "global" | "project";
343
+ profileId: string;
344
+ configHash: string;
345
+ socketPath: string;
346
+ }
347
+ ```
348
+
349
+ ### Rules
350
+ 1. The extension computes a runtime profile from effective config.
351
+ 2. The daemon status endpoint returns enough data to identify the active profile.
352
+ 3. If daemon profile != desired profile, the extension reloads or replaces it.
353
+ 4. Transcribe requests must include `backend`, `model`, and `language` even when a daemon is already running.
354
+
355
+ ### Socket strategy
356
+
357
+ Preferred:
358
+ - derive socket path from `profileId` or `configHash`
359
+ - example: `/tmp/pi-voice-<uid>-<hash>.sock`
360
+
361
+ Benefits:
362
+ - avoids collisions across projects/config scopes
363
+ - allows multiple compatible daemons if needed
364
+ - makes debugging easier
365
+
366
+ Minimum acceptable:
367
+ - keep one socket but always send explicit runtime parameters and force reload on mismatch
368
+
369
+ ### Daemon status contract changes
370
+ Add fields to `status`:
371
+ - `backend`
372
+ - `model`
373
+ - `language`
374
+ - `profile_id`
375
+ - `config_hash`
376
+ - `warm_capable`
377
+ - `last_error`
378
+
379
+ ### Daemon control changes
380
+ Add or refine commands:
381
+ - `status`
382
+ - `load`
383
+ - `reload`
384
+ - `shutdown`
385
+ - optional `backends`
386
+
387
+ ### Important note
388
+ Cloud backends do not need persistent warm models, but they still need a stable profile and health contract.
389
+
390
+ ## 7. Runtime module split
391
+
392
+ Refactor the monolithic `extensions/voice.ts` into smaller modules.
393
+
394
+ ### Proposed file layout
395
+
396
+ ```text
397
+ extensions/
398
+ voice/
399
+ index.ts
400
+ config.ts
401
+ onboarding.ts
402
+ diagnostics.ts
403
+ provisioning.ts
404
+ runtime.ts
405
+ daemon.ts
406
+ backends.ts
407
+ commands.ts
408
+ btw.ts
409
+ types.ts
410
+ ```
411
+
412
+ ### Responsibilities
413
+ - `index.ts`: extension registration and lifecycle wiring
414
+ - `config.ts`: load/save/migrate/effective config logic
415
+ - `onboarding.ts`: first-run and reconfigure flow orchestration
416
+ - `diagnostics.ts`: environment scan and health reporting
417
+ - `provisioning.ts`: install actions and remediation execution
418
+ - `runtime.ts`: audio recording and transcription dispatch
419
+ - `daemon.ts`: profile-aware daemon communication
420
+ - `backends.ts`: backend metadata and recommendation helpers
421
+ - `commands.ts`: `/voice`, `/voice doctor`, `/voice reconfigure`, `/voice info`
422
+ - `btw.ts`: BTW-specific logic only
423
+ - `types.ts`: shared TS interfaces
424
+
425
+ This should happen before adding more complex UI or provisioning logic.
426
+
427
+ ## 8. Portability strategy
428
+
429
+ The package currently assumes a macOS-ish environment in practice.
430
+
431
+ ### Current hidden assumptions
432
+ - `rec` exists and comes from SoX
433
+ - `brew` may be used to install native dependencies
434
+ - `python3` is available
435
+ - local model stacks work on CPU
436
+
437
+ ### Portability tiers
438
+
439
+ #### Tier 1: macOS Apple Silicon
440
+ Primary target for polished local onboarding.
441
+ - optimize recommendations for `faster-whisper`
442
+ - provide `brew` + `pip` install paths
443
+ - use this as the first-class supported path
444
+
445
+ #### Tier 2: Linux desktop
446
+ Supported with diagnostics-led setup.
447
+ - no Homebrew assumption
448
+ - more manual/local distro variance
449
+ - provisioning may need to fall back to manual commands
450
+
451
+ #### Tier 3: non-interactive / RPC / CI
452
+ Do not auto-onboard.
453
+ - commands should return structured errors
454
+ - diagnostics should still work
455
+ - setup should be re-runnable when UI exists
456
+
457
+ ### Portability policy
458
+ Document explicitly which flows are:
459
+ - fully automated
460
+ - partially automated
461
+ - manual only
462
+
463
+ ## 9. Package structure and metadata
464
+
465
+ ### `package.json` improvements
466
+ Add:
467
+ - richer description
468
+ - `repository`
469
+ - `homepage`
470
+ - `bugs`
471
+ - `keywords`
472
+ - scripts
473
+ - peerDependencies for Pi runtime packages
474
+ - `README.md` and `docs/` in `files`
475
+
476
+ ### Suggested scripts
477
+
478
+ ```json
479
+ {
480
+ "scripts": {
481
+ "typecheck": "bunx tsc -p tsconfig.json",
482
+ "check:python": "python3 -m py_compile daemon.py transcribe.py",
483
+ "check": "bun run typecheck && bun run check:python"
484
+ }
485
+ }
486
+ ```
487
+
488
+ ### Publish list
489
+ Include:
490
+ - `extensions`
491
+ - `daemon.py`
492
+ - `transcribe.py`
493
+ - `README.md`
494
+ - `docs`
495
+ - any shared backend metadata assets
496
+
497
+ ## 10. Recommended implementation sequence
498
+
499
+ ### Phase A — correctness foundation
500
+ Files:
501
+ - `extensions/voice.ts`
502
+ - `daemon.py`
503
+
504
+ Tasks:
505
+ - always pass `backend`/`model`/`language` to daemon transcribe requests
506
+ - make daemon status profile-aware
507
+ - stop eager daemon startup until config is validated
508
+ - add safer socket/profile strategy
509
+
510
+ ### Phase B — config and metadata foundation
511
+ Files:
512
+ - new `extensions/voice/config.ts`
513
+ - new `extensions/voice/types.ts`
514
+ - `transcribe.py` or shared backend manifest
515
+
516
+ Tasks:
517
+ - versioned config schema
518
+ - scope-aware save/load helpers
519
+ - onboarding state machine
520
+ - richer backend metadata contract
521
+
522
+ ### Phase C — diagnostics and provisioning foundation
523
+ Files:
524
+ - new `extensions/voice/diagnostics.ts`
525
+ - new `extensions/voice/provisioning.ts`
526
+ - `transcribe.py`
527
+
528
+ Tasks:
529
+ - machine-readable readiness checks
530
+ - install plan generation
531
+ - execution wrappers and failure classification
532
+
533
+ ### Phase D — extension modularization
534
+ Files:
535
+ - split current `extensions/voice.ts` into focused modules
536
+
537
+ Tasks:
538
+ - isolate BTW logic
539
+ - isolate runtime recording/transcription logic
540
+ - isolate command registration
541
+
542
+ ### Phase E — onboarding and doctor flows
543
+ Files:
544
+ - `extensions/voice/onboarding.ts`
545
+ - `extensions/voice/commands.ts`
546
+
547
+ Tasks:
548
+ - first-run wizard
549
+ - `/voice doctor`
550
+ - `/voice reconfigure`
551
+ - summary/health reporting
552
+
553
+ ### Phase F — package hardening
554
+ Files:
555
+ - `package.json`
556
+ - `README.md`
557
+ - `docs/*`
558
+
559
+ Tasks:
560
+ - metadata
561
+ - docs
562
+ - validation scripts
563
+ - release supportability
564
+
565
+ ## Risks and decisions to resolve early
566
+
567
+ ### 1. Shared metadata source of truth
568
+ Decide whether backend metadata lives in:
569
+ - Python only,
570
+ - TypeScript only,
571
+ - or shared JSON.
572
+
573
+ Recommendation: **shared JSON or TS-generated JSON**.
574
+
575
+ ### 2. Auto-install safety policy
576
+ Decide what the extension may execute automatically:
577
+ - just diagnostics
578
+ - diagnostics + optional package install
579
+ - diagnostics + fully automatic remediation by default
580
+
581
+ Recommendation: **opt-in auto-install during onboarding** with clear user confirmation.
582
+
583
+ ### 3. Daemon multiplicity
584
+ Decide whether to support:
585
+ - one daemon per config profile
586
+ - or one daemon that reloads in place
587
+
588
+ Recommendation: **profile-derived socket path**, with reload support as a secondary optimization.
589
+
590
+ ### 4. Cloud provider expansion
591
+ Today only Deepgram is implemented for cloud. The config model should be provider-ready even if the first polished flow only supports one cloud backend.
592
+
593
+ ## Definition of done for the technical architecture
594
+
595
+ The architecture work is complete when:
596
+ - config has a versioned schema and migration path
597
+ - onboarding state is explicit and persisted
598
+ - project/global scope is saved intentionally
599
+ - backend metadata supports recommendation and install logic
600
+ - diagnostics returns structured readiness data
601
+ - provisioning executes from an install plan, not ad-hoc shelling out
602
+ - daemon/runtime profile selection is deterministic
603
+ - stale daemon config cannot silently override saved user intent
604
+ - code is split into maintainable modules
605
+ - package metadata and validation scripts support shipping the package confidently
606
+
607
+ ## Final recommendation
608
+
609
+ Do the technical remediation in this order:
610
+
611
+ **runtime correctness -> config/schema -> backend metadata -> diagnostics -> provisioning -> modularization -> package hardening**
612
+
613
+ That order prevents the team from building a polished onboarding flow on top of an unstable runtime contract.
@@ -0,0 +1,69 @@
1
+ # pi-voice QA matrix
2
+
3
+ This checklist separates what has already been verified from what is still worth running on a target release machine.
4
+
5
+ ## Automated checks completed
6
+
7
+ - [x] TypeScript compiles via `bun run typecheck`
8
+ - [x] Python files compile via `python3 -m py_compile daemon.py transcribe.py`
9
+ - [x] Config migration and scope tests pass
10
+ - [x] Diagnostics recommendation tests pass
11
+ - [x] Provisioning-plan helper tests pass
12
+ - [x] Onboarding fallback/finalization tests pass
13
+ - [x] Model-detection metadata tests pass
14
+ - [x] Model-aware recommendation and labeling tests pass
15
+ - [x] Aggregate verification passes via `bun run check`
16
+
17
+ ## RPC-assisted / smoke checks completed
18
+
19
+ ### First-run onboarding
20
+ - [x] Fresh install with no config triggers onboarding prompt on interactive startup
21
+ - [x] Choosing `Remind me later` suppresses the prompt during the defer window
22
+ - [x] `/voice reconfigure` reopens the onboarding flow
23
+ - [x] Partial legacy config re-enters onboarding instead of being treated as complete
24
+ - [x] API-vs-Local choice appears correctly in the terminal UI
25
+
26
+ ### Local mode and model-aware behavior
27
+ - [x] Local path still offers backend choices even when no cached models are found
28
+ - [x] Suggested commands are sensible for missing SoX and local backend installs
29
+ - [x] Missing-model path is represented cleanly through model-aware provisioning/manual-step logic
30
+ - [x] `/voice doctor` distinguishes current-config repair from recommended alternative
31
+ - [x] Backend scan exposes `installed_models` and `install_detection` metadata
32
+ - [x] `/voice backends` surfaces model-aware backend summaries and detection hints
33
+ - [x] `/voice info` surfaces current model readiness and scope details
34
+ - [x] `/voice test` surfaces current model readiness plus targeted guidance
35
+
36
+ ### Scope and reconfiguration
37
+ - [x] Project scope writes to `.pi/settings.json`
38
+ - [x] Reconfigure path saves updated choices
39
+ - [x] Repair-needed states stay incomplete instead of being falsely marked complete
40
+
41
+ ## Remaining target-machine checks
42
+
43
+ These are the highest-value checks still worth running on the actual release machine.
44
+
45
+ ### Real audio / device validation
46
+ - [ ] Hold-to-talk with a real microphone transcribes successfully after setup
47
+ - [ ] `Ctrl+Shift+V` fallback recording works in the target terminal
48
+ - [ ] `Ctrl+Shift+B` BTW voice path still works end-to-end
49
+
50
+ ### Real provider / ready-now validation
51
+ - [ ] Cloud setup completes successfully when `DEEPGRAM_API_KEY` is present
52
+ - [ ] Local setup completes successfully on a machine with SoX installed and a supported backend available
53
+ - [ ] Runtime uses the selected backend/model after reconfiguration
54
+ - [ ] Config-scoped socket behavior avoids silent stale-daemon reuse under real session switching
55
+
56
+ ### Installed-model specific validation
57
+ - [ ] At least one machine with an already cached local model shows an explicit ready-now / already-installed path in onboarding
58
+ - [ ] At least one machine with backend installed but selected model missing shows clear download-required messaging
59
+ - [ ] `/voice info` and `/voice test` reflect the selected model's readiness accurately on a machine with real caches
60
+
61
+ ## Suggested execution order
62
+
63
+ 1. Fresh install / first-run prompt
64
+ 2. Remind-me-later and reconfigure path
65
+ 3. Project-scope save path
66
+ 4. Model-aware local path with no cached models
67
+ 5. Installed-model ready-now path on a machine with real caches
68
+ 6. Cloud/API happy path with valid credentials
69
+ 7. Real microphone / hold-to-talk sanity pass