From 15b020086d084d7e7e6f691c8135f2af59eeddcf Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 11 Jul 2026 03:06:57 -0500 Subject: chore: close bt doctor Phase 0 as a dated log entry --- todo.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'todo.org') diff --git a/todo.org b/todo.org index c0543ca..8c394cb 100644 --- a/todo.org +++ b/todo.org @@ -45,8 +45,8 @@ On v1 completion: flip the spec's status heading to IMPLEMENTED (dated history l :SPEC_ID: 3d4d61c4-e5df-44e9-b8e0-40b31452c3f7 :END: Build the [[file:docs/specs/2026-07-11-bt-doctor-expansion-spec.org][bt doctor expansion]] (DOING). Adds a dmesg firmware-hint probe (names the missing blob on a no-adapter fault) and a boot-enablement probe (catches an adapter disabled at boot) to the shipped bt doctor (=~/.dotfiles/bluetooth/=). Phase 2 is gated on the shared cross-panel privilege model; Phases 0-1 build now. Archsetup owns the dotfiles work end to end. -*** TODO [#B] Phase 0 — the two read-only probes :solo: -Pure engine, no repair change. The dmesg firmware-hint reader (no-adapter branch, bounded =cmd.run(journalctl -k)= reusing the =doctor.py:84= precedent, per-vendor signature match) and the boot-enablement reader (AutoEnable from main.conf [Policy], =systemctl is-enabled=, TLP list). Both report into =diagnose()='s dict feeding the human summary + =--json=. Fault fires only on explicit AutoEnable=false / disabled service / TLP entry — bluez's default is true, so absent config is auto-enable-on and never a fault. Tests: canned journal buffer per vendor + injected main.conf/is-enabled/tlp states. Verify: fakes + =make test=. Solo. +*** 2026-07-11 Sat @ 03:06:32 -0500 Built the two read-only probes +New module =bluetooth/src/bt/probes.py= plus =doctor.py= wiring, on dotfiles main (=d19fdca=, pushed). Two reads the diagnose chain never did: =firmware_hint()= scans the current boot's kernel log for per-vendor firmware-load failures (Intel ibt-*.sfi, MediaTek BT_RAM_CODE, Realtek rtl_bt, Broadcom .hcd, Qualcomm QCA), returning the named blob via a bounded =cmd.run(journalctl -k)= that reuses the =doctor.py:84= precedent; =boot_enablement()= reads three boot-persistence signals (bluez AutoEnable from main.conf [Policy], =systemctl is-enabled bluetooth=, whether TLP lists bluetooth in =DEVICES_TO_DISABLE_ON_STARTUP=). =diagnose()= gates the firmware read to the no-adapter branch and the boot read to the soft-blocked/powered-off branch, so a healthy run reads neither; the raw signals ride a new =probes= key that =doctor()= carries into =--json=. Detection only: no verdict, formatter, or repair change (that's Phase 1). Every read degrades to None on an unreadable tool/file, so a probe that can't see never invents a fault. AutoEnable absent/unset reads None, not false, matching bluez's compiled default of true, so only an explicit =AutoEnable=false= is the fault. New env roots for tests (=BT_MAIN_CONF=, =BT_TLP_CONF=, defaulting to absent temp paths in the Sandbox base so no test reads real /etc); =fake-journalctl= branches on =-k=, =fake-systemctl= answers =is-enabled bluetooth=. 125 bt tests, full =make test= green; =/review-code= approved (no Critical/Important; one Minor noting the firmware read also covers the btctl-unavailable branch, harmless). Inbox note sent to dotfiles. *** TODO [#B] Phase 1 — firmware-hint Guide verdict :solo: =diagnose= emits =no-adapter-firmware= (blob name in evidence, Reboot-tail Guide) on a signature match; falls back to the generic no-adapter otherwise. No auto-fix — a Guide, so no privilege dependency; lands independently of the shared model. The distinction rides existing =evidence=/=next_action= (no formatter change); an additive =schema.step= =code= key only if a machine identifier is wanted (locked test-contract ripple). Verify: fake journal fixtures + =make test=. Solo. *** TODO [#C] Phase 2 — persistent-power verdict + fix -- cgit v1.2.3