| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
I ran spec-response Phase 6 on both READY specs. Each gets a SPEC_ID-bound parent task in todo.org with one child per implementation phase. Both specs flip from READY to DOING.
Only the read-only detection phases are buildable now, so they're marked solo: net Phase 0 (the control-plane probe) and bt Phases 0-1 (the two probes plus the firmware-hint Guide verdict). The privileged phases stay lower priority and carry a note: they're gated on the shared cross-panel run-time privilege model that doesn't exist yet. Shipping them before the Confirm floor would let --fix run root ops via passwordless sudo ungated.
I held off writing the manual-testing checklists. The phases that need live or reboot verification are the blocked ones, so their checklists would be planning work that can't start yet.
|
| |
|
|
|
|
|
|
|
|
| |
I ran spec-response on both, then two more skeptical review rounds until each reached Ready with caveats, no blocking findings. I verified every current-behavior claim against the live engine before each response. The skeptical passes earned their place by catching real blockers the first round missed.
Net: my round-1 "redaction copy/--json surface" was invented. That surface doesn't exist: SSID redaction is event-log-only and --json is raw. I re-resolved it as parity with the existing link-step behavior, plus a separate task for the systemic gap. I also made all three control-plane verdicts fixable, since a terminal outcome would never run its own fix (doctor.py:181). And I repointed the auth classifier at the profile key-mgmt and scan-security signals that carry the SAE/hidden distinction.
Bt: the AutoEnable default is true, not false (bluez 5.87), so round 1 had the "dead every boot" premise backwards and would false-positive on healthy machines. The fault now fires only on an explicit AutoEnable=false, a disabled service, or a TLP entry. The verdict "code" is an additive schema.step key, not one that exists today.
Both specs carry one caveat: Phases 1-2 need the shared cross-panel run-time privilege model, which doesn't exist yet. A hard ordering gate now sits on each: shipping the Privileged verdicts before the Confirm floor would let --fix run root ops via passwordless sudo ungated. Only Phase 0 is buildable today.
|
| |
|
|
|
|
|
|
|
|
| |
Reviewed both DRAFT expansion specs against the live engines. Both stay Not ready: three open decisions apiece plus one blocking finding each.
Net: the Security dimension claims connection names are already redacted, but redact.py covers only SSID, MAC, IP, secret-keys, and portal_url, so the new keyfile-perms and rival-manager verdicts would leak a connection name into the wall and --json. Four non-blocking fixes alongside it: nm-restart's scope was overstated, is-enabled isn't used yet, some message text was listed as classifier verdicts, and the priv.py dispatch integration wants naming.
Bt: the doctor has no named-verdict layer to hang the proposed no-adapter-firmware and powered-off-persistent verdicts on. A step carries a pass/fail/warn/info status and the run an ok/warn/fail overall, nothing more. How each new verdict is represented has to be settled before Phase 1. Three non-blocking notes cover the widening sudoers surface, the real diagnostic surface, and the bounded journalctl precedent.
Both designs are sound and target verified-real gaps: neither engine reads the config or logs the specs propose to add.
|
| |
|
|
|
|
|
|
| |
I ran the audio doctor's design arc for the net and bluetooth doctors: a blind by-layer research catalogue of failure modes, a symptom-cluster triage, then a spec per doctor.
The taxonomy holds ~74 network and ~55 bluetooth distinct root causes, each sourced to a forum or issue-tracker report, sorted into eight network and five bluetooth symptom clusters. The clusters are keyed to each doctor's existing probe ladder, so the fix-versus-guide boundary falls along the tiers the doctor already walks. Every entry carries a remedy class (auto, privileged, reboot-tail, or guide), reusing the audio doctor's four-class run-time privilege model.
The two specs are expansions, not rewrites. The net doctor is already the most mature of the three: its classifier reaches six of the eight clusters today, so its spec adds only the control-plane cluster (a rival network manager, a masked NetworkManager, a bad keyfile) and sharper auth naming. The bt doctor's chain is structurally right but blind at both ends, so its spec adds a probe that names the firmware blob the kernel already logged and a probe that catches an adapter that power-on won't keep on across reboots. Both stay DRAFT with three open decisions each, headed for spec-review.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
A blind resample tested whether the nine-cluster taxonomy was representative or an artifact of the first sweep. Ten agents drew 108 fresh reports through five different doors per direction, mostly non-Arch and 2024-2026, none shown the clusters. Zero forced a new cluster. About 70 re-found existing entries. The other 34 were new distinct root causes that all fit existing clusters.
I folded the 34 new entries in, 16 input and 18 output, each tagged with its cluster and remedy class, and recorded the test and its verdict. The clusters are complete and stable. Entries keep growing under them without changing the design.
|
| |
|
|
|
|
| |
I sorted both directions into nine symptom clusters each, every entry tagged Auto, Privileged, Reboot-tail, or Guide under the privilege model. The clusters mirror the doctor's probe ladder, so the boundary between what it fixes and what it can only guide falls along the tiers it already probes.
Two findings are worth keeping. The buildable core reduces to five primitives on both sides (set-default, set-card-profile, unmute, restart-services, config-drop-in), so the breadth is in the diagnosis, not the remedies. And the clusters imply three new read-only probes: dmesg-pattern hints, an unmute-doesn't-stick signature, and a re-probe-after-idle.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
This catalogues real, user-reported ways the microphone and speakers fail on Linux, to feed the audio doctor's triage. It holds 58 input and 59 output distinct root causes, across eight layers each: kernel/driver/firmware, ALSA, PipeWire, Bluetooth, HDMI, USB, app/portal, hardware. Every entry carries its symptom, cause, concrete fix, a sudo/reboot tag, and a source.
The sudo/reboot tag is the triage lever. A no-sudo, no-reboot fix is a candidate for a doctor remedy. A firmware, BIOS, or physical fix can only ever be a printed instruction. Triage into build, guide, or out is the next pass.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
The doctor shipped end to end, so the spec goes to IMPLEMENTED and the task closes with a dated record of what landed.
Three things the Decisions did not anticipate are written into the history rather than left for a reader to infer. A tenth verdict for missing tooling, because an absent pactl is an unobserved stack and not a broken one. A re-probed marker between a fix run's two row blocks. And DIAGNOSE as the read-only key's name, which Craig settled after asking why this panel carries two keys where the net panel carries one.
I filed the wall-controls convergence as its own task. Craig wants the net panel's copy and close pair on every output wall, and today no two of the four agree.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All eight decisions resolved. DOCTOR is a section-header key; CLI-first with
the GUI as a face; hung and dead are two verdicts sharing one remedy; the
remedy tiers stand as drafted; a stream-active guard refuses the audible
remedies and is overridable by pressing again; xruns stay out of v1.
Two consequences the questions did not make obvious. Taking the guard is what
lets the pipewire-pulse restart stay at Confirm — the danger lives in the state
of the machine, not the identity of the remedy. And the guard must read stream
state from pw-dump rather than pactl: the remedies it protects are the ones you
reach for when the Pulse layer is dead, so a pactl-fed guard would go blind
exactly when it is needed.
Tier 4 drops its xrun probe to match the decision, rather than leaving the
probe list contradicting the answer.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The draft said build_status had no pactl timeout and froze the panel. Driving
it disproved that: pactl.run defaults to timeout=8 and raises PactlTimeout, so
the panel degrades.
The real defect was narrower and is now fixed. Two of build_status's four reads
sat outside its degrade guard, so a server that answered the device lists and
then stopped answering raised out of a function contracted to return ok:False,
and waybar's audio module died rather than dimming.
Corrected in place with the reasoning, rather than dropped, since a spec that
quietly loses a wrong claim teaches nothing about why it was wrong.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Answers the four questions the request asked, from a live survey rather than
from memory. There is no PulseAudio: the stack is pipewire, wireplumber, and
pipewire-pulse, all user-scope, so no remedy in this feature needs sudo — which
is why it mirrors the net panel's doctor rather than the maintenance console's
privileged verb table.
Two findings shape the design. pactl hangs against a server that accepts and
never answers, which is exactly the fault a doctor exists to diagnose, so every
probe is bounded. And the panel cannot diagnose itself, because pactl is the
layer most likely to be down — the probes read systemctl and pw-dump before
they touch it.
Filed the panel's own missing timeout as a separate bug. It freezes the audio
panel today, independently of any doctor.
Seven decisions left open; the spec is DRAFT and nothing gets built until they
close.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The repo carries an open task to publish it, and docs/ leaked things a clone
could neither use nor should see.
Absolute paths under one user's home become the repo root, a home-relative
path, or a named variable, so the snippets stay runnable for anyone. The
testinfra example takes its user from an env var instead of hardcoding one.
References into a private sibling project and into the gitignored tooling
directory are replaced by what they mean; as written they were dead links in
any clone but the author's.
Five documents claimed a co-author who is not a person. An #+AUTHOR line
survives conversion into docx, a wiki page, or a PDF, so it is worth being
exact about: these documents have one author.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The four host capability inventories, the TrueNAS hardware specs, and the
ratio USB/xHCI record now live as roam nodes under ~/org/roam/hardware/,
linked from the Homelab Hardware Inventory index. The copies here are gone.
Carried rather than pointed at. A pointer keeps one canonical copy, but a
third project that discovers a durable hardware fact would then have to write
into this repo to record it, which the cross-project rules forbid — so the
fact would land in an inbox instead of on the device's page. Moving keeps one
canonical copy without closing the write path.
system-health-check.org resolves a host's inventory by its #+HOSTNAME: keyword
under ${ROAM_DIR:-$HOME/org/roam}/hardware/, never by filename: a node's
timestamp prefix does not survive a rename. A host with no roam clone takes the
same NO INVENTORY FILE path it always did.
strix-soak-watch.org lands here from home, beside the workflow whose Phase 3
invokes it. It is a workflow, not an inventory page.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
The workflow and the four host capability inventories move here from the home project. System maintenance is archsetup's domain, and this puts the thresholds TOML and both of its consumers in one repo.
The workflow's prose severity rules now cite the installed TOML keys, and the TOML wins on disagreement. Inventory paths point at docs/homelab-inventory/. A note routes routine ratio/velox checks to the maint CLI, leaving this workflow for the non-Arch hosts and forensic deep dives.
Only the #+HOSTNAME: capability inventories moved (ratio, velox, mybitch, truenas, plus the truenas hardware-specs asset they link). The personal gear records stay in home, and the home-side removal is handed off through its inbox.
|
| | |
|
| |
|
|
|
|
| |
The spec encodes the converged 2026-07-06/07 design as 13 decisions and 13 phases (CLI-first maint package, four-layer test strategy) and carries its full review trail inside, live-verified on ratio. Late calls landed during authoring: the bar glyph replaces custom/sysmon, doubles as the laptop battery display, and keeps the btop scratchpad on right-click.
todo.org now carries the build: 13 phase tasks under a SPEC_ID-stamped parent, the manual-testing collector, the flip-to-IMPLEMENTED closer, and the vNext deferral.
|
| |
|
|
|
|
|
|
| |
The design doc replaces the install-health framing in system-monitor-design-ideas.org with a maintenance console: dense metric subpanels behind a persistent selector, a doctor that streams into a results wall, determinate remedies only (guard-armed updates, curation lifecycles for noise, listeners, containers, and orphans), rotary band selectors on the tall subpanels, and a CLI-first build with a four-layer test strategy. Every decision is dated in the doc.
Prototypes A-E5 keep the exploration path: five divergent layouts converging into E5, a fully interactive simulation whose GOOD/BAD snapshots become the build's test fixtures.
todo.org gains the spec-create task, the panel keybinding-family task, and scope notes on the net/bt doctor retrofit.
|
| |
|
|
|
|
|
| |
Design prototype for the push-to-talk bar indicator: an always-present outline
tag (account-voice glyph) left of the mic — dim grey when off so the bar never
reflows, gold + glow when armed, brighter while transmitting, click-to-toggle.
The states and icon were settled against this before wiring it into waybar.
|
| |
|
|
| |
Records Phase 5 of the audio signal-metering spec: a per-device three-state activity lamp on each output/input row, so the panel shows which specific device is carrying audio, not just the default. GUI-only over the per-device state field already in the engine. Adds the live-check to the manual checklist; the per-row live level meter stays the deferred vNext.
|
| |
|
|
| |
Records the signal-metering layer for the audio panel: a three-state activity lamp from the pactl state field, and a windowed peak meter feeding the VU needles, keyed per device so per-device metering stays a later GUI-only change. Two review rounds before build (the first caught a parec sample-rate-vs-update-rate bug verified live); marked implemented across four dotfiles commits. Live-eyeball checks filed as a manual-testing checklist.
|
| |
|
|
| |
todo-cleanup moved the closed instrument-console panel-bug batch (net/bt/audio) to Resolved. Bring the system-monitor design-ideas capture under version control.
|
| |
|
|
|
|
| |
The timer-panel UI/UX redesign built and shipped to dotfiles across five phased commits. This captures the archsetup-side records.
The three design prototypes (the three-directions study, the hero-rack iteration, and the final) land under docs/prototypes, which the spec's Prototype iterations section links. The spec flips DOING to IMPLEMENTED with a history line summarizing the build. The manual-testing checklist is rebuilt around the redesigned panel (repeat timers, recurring alarms with snooze and a ringing state, the configurable pomodoro cycle, the stopwatch sweep dial, locked presets, and bar-tooltip parity), and the two obsolete fuzzel-dialog tests are marked superseded. A dated entry under the closed feature task records the redesign.
|
| |
|
|
|
|
| |
tests filed
The timer GTK panel built and shipped to dotfiles (4 commits). Flipped the spec to IMPLEMENTED, closed the Timer GTK panel task, and filed the live-verification checklist (bar-opens-panel, create/validate, fire-time sort, pause/cancel/promote, stopwatch lap/stop/save, 10-cap + live countdown) under Manual testing and validation.
|
| |
|
|
| |
Craig directed the build. Consolidated the four resolved decisions with his cj input from the sibling timer-module spec: GTK app in the instrument-console look, a queue/output-wall auto-sorted by fire time, stopwatch lap/stop with saveable runs, notify integration, 5/25-min configurable defaults, up to 10 timers, and widget-gallery elements. wtimer stays the engine; the bar's fuzzel creation flow retires and the module opens the panel.
|
| |
|
|
| |
Craig's 2026-07-04 roam input on the panel's open "few other things" question: it gathers the mouse/trackpad, no-sleep, and auto-dim toggles and adds a wallpaper manager (where the displaced waypaper lands) with its own depth — multiple source directories, persistent switching, and a sunup/sundown day-night pair. Flagged that the wallpaper piece may warrant its own sub-spec.
|
| |
|
|
|
|
| |
I gathered all five self-contained HTML/CSS design prototypes into one home: the instrument-console pair (moved from assets/), plus the net-panel rescan, sound panel, widget gallery, and waybar redesign (moved out of working/). Added a README index and updated every inbound link: build summary, the instrument-console and audio specs, and todo.org.
Also fixed a broken link the earlier sort left in the build summary. It still pointed at the instrument-console spec's old docs/design/ path after the move to docs/specs/.
|
| |
|
|
| |
The specs were sorted into docs/specs/ on another machine, from a copy of this one that predated the 2026-07-03 panel-family design discussion. That lost the faceplate refinements. I re-applied them: the instrument-console faceplate aesthetic in place of the plain palette note, the audio/bt Kin row, a dated Status line, and the still-open "few other things" scoping question. The four decisions that pass resolved stay closed. Only the question it never addressed comes back.
|
| |
|
|
|
|
| |
Both DRAFT panel specs had open design decisions blocking their builds. I resolved them. Timer panel: standalone rather than folded into desktop-settings, the fuzzel flow retires once the panel lands, the preset chips gain 10m/30m/2h, and live state comes from a new wtimer watch mode instead of 1s polling. Desktop-settings panel: auto-dim and airplane collapse into the panel while touchpad and caffeine stay on the bar, Super+Shift+G opens it, the code lives in dotfiles settings/ beside net/, and the brightness slider floors at 5%.
Both stay DRAFT and decision-complete, ready for a spec-review before build.
|
| |
|
|
| |
Moved the seven formal specs from docs/design/ into docs/specs/, each stamped with a lifecycle status heading: four IMPLEMENTED (bluetooth, net-other-interfaces, audio, instrument-console), one CANCELLED (file-manager-swallow), two DRAFT (desktop-settings, timer). Rewrote the seven todo.org links to the new paths. The two -spec.org files without the spec spine (waybar-network-module, waybar-timer-module) stayed in docs/design/ as notes.
|
| |
|
|
| |
The audio panel got built end-to-end in a no-approvals speedrun (the code lives in the dotfiles repo). This is the archsetup-side bookkeeping: the spec flips DRAFT to IMPLEMENTED with all five Decisions resolved, the todo task closes with the resolution, and the live-eyeball checklist (default switching, faders, master quick-mute, and push-to-talk in a real meeting) lands under Manual testing and validation.
|
| |
|
|
| |
Closed out the panel rebuild. Both panels verified live on velox: 46 suites and both AT-SPI smokes green, the dead-code removal shipped in dotfiles f4e688e, and the render carries the phase-3/4/5 screenshots since no view code changed. Flipped the parent task and its three folded children (network panel redesign, bt switch placement, bt rename) to DONE, ticked the spec's last phase, and flipped the spec to IMPLEMENTED. Filed the approved prototype and the build summary flat into assets/ with dated names, updated the inbound links, and dropped the working dir. The real-device bt interactions (pair, rename, connect, forget, discoverable, power, low-batt badge) can't be auto-driven, so they're a manual-test checklist.
|
| |
|
|
|
|
| |
Ticks spec phase 5 and records the two-commit bt rebuild (dotfiles 5318b34 layer + 66f03d9 view). Phase 6 (live verify + close-outs + IMPLEMENTED) remains.
Claude-Session: https://claude.ai/code/session_013xt96EetpueCFriY4jGyfw
|
| |
|
|
| |
Ticked spec phases 3 and 4 (net view rebuild + interactions, dotfiles 800ef60) and logged the dated todo entry. Phases combined into one commit because a view-only intermediate is a broken panel. BT panel (phase 5) next.
|
| |
|
|
|
|
| |
Tick spec phase-2 checkbox and record the dotfiles 81ec9c3 build (net GTK-free presenter layer + engine verbs) as a dated entry under the instrument-console parent task.
Claude-Session: https://claude.ai/code/session_013xt96EetpueCFriY4jGyfw
|
| | |
|
| |
|
|
|
|
| |
nautilus
Craig corrected the target: Super+F opens the dirvish popup (an Emacs frame), so the swallow belongs in elisp, where it's strictly better — Emacs launches the viewer, so a directly-spawned handler plus a process sentinel gives exact hide/restore and a failure notify, no window-event heuristics. Spec cancelled with the gio double-fork finding kept for reference; task closed as reassigned.
|
| |
|
|
| |
Hyprland's enable_swallow matches by PID ancestry, and nautilus's gio launch path orphans the handler process (verified live: the spawned viewer reparents to init while the launcher still runs). The spec designs an event-listener daemon on the IPC socket instead — swallow nautilus when a window opens while it's active, restore on that window's close. DRAFT with four decisions pending review.
|
| |
|
|
| |
scripts/import-wireguard-configs.sh imports the seven Proton configs into NetworkManager with autoconnect forced off. Each config stages through a wgpvpn.conf temp copy (NM's import name must be a valid interface name; several config names exceed the 15-char limit) and is renamed by the UUID parsed from the import output, so a stray same-named connection can't be hit. A leftover wgpvpn connection — a run that died between import and rename, autoconnect still armed — makes the script refuse to run. 10 tests over a fake nmcli; velox migration verified (all seven wireguard, autoconnect no). The tunnels spec is implemented: all six phases shipped.
|
| | |
|
| |
|
|
| |
Phase 5 needed no new install code: the waybar module, keybind, and shared panel css ride the dotfiles hyprland tier the installer already stows, and sudoers is covered by the existing grant. I added hyprland-gated assertions instead: bt bins stowed executable, custom/bluetooth in the waybar config, the bt-panel bind in hyprland.conf, panel.css present. This closes the bluetooth-panel task and flips the spec to implemented.
|
| |
|
|
| |
I dropped blueman from the desktop_environment bluetooth loop (bluez + bluez-utils stay) and added the VM assertions: bluetooth stack installed, blueman absent as the retirement regression guard. No new sudoers rule was needed for bt-priv, since the existing blanket grant already covers systemctl restart bluetooth.
|
| | |
|