aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/2026-07-10-audio-doctor-input-side-spec.org
Commit message (Collapse)AuthorAgeFilesLines
* docs: fold the failure taxonomy into the input-side specCraig Jennings2026-07-101-0/+33
| | | | | | I grounded the spec in the taxonomy and its triage. A new "Verdict clusters and remedy classes" section maps the doctor's verdicts onto the nine saturation-tested symptom clusters, ties the four remedy classes to the run-time privilege decision, and names the three new probes the taxonomy implies: dmesg hints, the unmute-doesn't-stick signature, and re-probe-after-idle. v1 stays the buildable core, phases 0 through 4. The rest of the taxonomy is staged as later phases so v1 isn't blocked on it.
* docs: add the run-time privilege model as a doctor decisionCraig Jennings2026-07-101-2/+12
| | | | | | | | The input and output doctor reaches firmware, ALSA saved state, modprobe, and packages, which need root. The parent spec decided "no sudo anywhere," correct when the feature was user-scope PipeWire. This supersedes that. The doctor resolves its privilege at run time from three signals: passwordless sudo (sudo -n true, which never hangs), a tty to prompt at, and whether it is the GUI panel. Four remedy classes follow. Auto is user-scope and runs anywhere. Privileged needs sudo, so it runs where passwordless sudo exists, prompts on a CLI, and degrades to Guide otherwise. Reboot-tail runs the applicable part, then instructs the reboot. Guide is physical, BIOS, or wait-for-upstream. Passwordless sudo is not consequence-free, so every Privileged and Reboot-tail remedy defaults to Confirm or Arm, never silent Auto. This was Craig's call, and he wants it as a cross-panel standard. I filed a task to factor the privilege resolution into a shared helper the net, bluetooth, maint, and audio doctors all use.
* docs: record the second review pass on the input-side specCraig Jennings2026-07-101-4/+35
| | | | | | | | I ran a second pass across four critical lenses: buildability, technical correctness, adversarial failure-modes, and internal consistency. The technical foundations held. I verified every load-bearing code and /proc/asound claim against the real tree. I recorded eight findings, two of them blocking. The mic-unmute remedy fails open on an unreadable graph, and a privacy event must fail closed. A Bluetooth or USB-non-ALSA mic classifies as no-mic-hardware because it never appears under /proc/asound. I also fixed three mechanical inconsistencies in place: a remedy miscount, and two stray OUTPUT/INPUT doctor-key labels the SPEAKERS/MICROPHONE rename missed. The spec stays DRAFT. The blocking findings gate it from READY.
* docs: fold Craig's spec notes and a review finding into the input-side specCraig Jennings2026-07-101-14/+105
| | | | | | | | | | | | Craig left four notes on the draft. This closes all of them. He ratified two open decisions: don't rebuild push-to-talk, since the source-mute is the safety property, and read /proc/asound directly for the kernel tier. Both close DONE. He flagged a naming collision. The doctor keys can't be OUTPUT/INPUT, because the CONTROLS section already carries INPUT/OUTPUT mute toggles. They become SPEAKERS and MICROPHONE, with a distinct diagnostic style held consistent across every panel. I recorded it as a new decision and left the visual treatment open for his eye. He asked for a failure-modes map, so the spec gains a table of every fault by probe tier with its verdict and remedy, output and input together. A spec-review had also left two blocking findings. The kernel-to-graph one was real: ALSA card ids and PipeWire node names are different namespaces, so "compare the sets" was undefined. I took the reviewer's coarse rule as the v1 definition. mic-unrecognized fires when the kernel capture set is non-empty and the graph has zero non-monitor hardware sources. Per-device correlation is logged as vNext. That finding closes. The open-decisions one stays until the last three land.
* docs: close the audio-doctor CLI decision, symmetric direction flagsCraig Jennings2026-07-101-8/+9
| | | | audio doctor takes only --fix and --force today, so a lone --input would read as a special case on a bare command. Craig's call: add both --output and --input as explicit flags and alias bare audio doctor to --output. The directions are named symmetrically, --input has a sibling, and nothing that scripts the bare command breaks.
* docs: spec the audio doctor's input side, one doctor per directionCraig Jennings2026-07-101-0/+328
The doctor never examines the microphone. diag collects default_source and default_source_present, the classifier reads neither, so a muted mic, a stale default source, and a mic the sound server can't see all classify as healthy. Chrome losing the mic this morning surfaced it: the stack was genuinely fine and the doctor had nothing useful to say. The design grew past the gap in one conversation. An empty source list is normal on a mic-less desktop and a failure on a machine that should have one, and no probe can tell those apart. The missing fact comes from the user's finger: a doctor key on each of the OUTPUTS and INPUTS section headers, where pressing the input one asserts a mic should exist. That retires the DOCTOR header key I shipped hours earlier, and it dissolves the precedence question a single classifier would have faced. A new probe tier sits below PipeWire. /proc/asound lists capture-capable cards, needs no package, spawns no process, and can't hang, so it separates "the software lost a microphone the kernel sees" from "nothing is plugged in". Push-to-talk stays as it is. It mutes the source, the one state where the server guarantees nothing is captured. A link-based push-to-talk fails open, and a crash mid-hold is a hot mic reading as muted. The doctor reads ptt.read_state() instead of guessing. Four decisions are open. Three are closed.