aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* docs: close the audio-doctor decisions, spec is READYHEADmainCraig Jennings8 hours2-19/+40
| | | | | | | | | | | | | | | | | 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.
* docs(todo): close the minimal-tier zsh PATH gapCraig Jennings8 hours1-1/+6
| | | | | Fixed in dotfiles c6a7878. Recorded that the test asserts the tier invariant rather than the file, since a per-file fix is what missed the tier.
* docs(todo): task-review pass over the oldest-unreviewed batchCraig Jennings9 hours1-7/+19
| | | | | | | | | | | | Seven tasks walked. Three carried a topic tag but no type tag, so they were invisible to any filter that asks what kind of work they are. The net/bt realtime-lamp retrofit gains :solo:. Its scope question was settled in July, and what remains is buildable and testable without a decision. Priorities held on review. The zsh PATH gap and the zfs base-image failure both already sit where the severity-by-frequency read puts them, and the keybinding family still turns on a design choice nobody has made.
* docs(todo): one manual-testing parent, and remove the last false bylinesCraig Jennings9 hours5-19/+23
| | | | | | | | | | | | | | The maintenance console's in-person checklist was a second top-level "Manual testing and validation" task. It is now a child of the one parent, so the pending checks live in a single place rather than two the agenda shows apart. The audio doctor moves to [#B]. Its spec is written and Phase 0 shipped; six decisions are all that stand between it and a build, which is active backlog rather than parking lot. Four dated artifacts still credited a co-author who is not a person. They are records, but they are tracked and would publish, so they carry one author now like everything else.
* docs(todo): reconcile the open tasks against realityCraig Jennings10 hours1-62/+93
| | | | | | | | | | | | | | | | | | | | Archived the nine tasks that shipped today. Verified the rest against the world rather than against memory, and recorded what moved. The telega watch item has not recurred: zero assertions in the server log, and the newest coredump predates the fix. It is a watch item with no defect behind it, so it drops to [#D] per the severity-by-frequency read. The net module's Phase 4 is filed and waiting on the dotfiles project, which already tracks it — tagged blocked rather than re-sent. The manual-testing container carried no priority and no type tag, which kept the project's largest live collection of pending checks out of the agenda entirely. It has both now, plus a check for the one thing today's work cannot verify without a reboot. The release epic gained what the docs scrub landed, and what it uncovered: four tracked files still name a co-author who is not a person.
* docs: correct the audio-doctor spec's timeout claim, close Phase 0Craig Jennings10 hours2-10/+19
| | | | | | | | | | | | | | 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.
* docs: spec the audio panel doctorCraig Jennings10 hours2-1/+262
| | | | | | | | | | | | | | | | | | | | 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.
* docs: remove personal paths and false co-authorship before releaseCraig Jennings12 hours7-17/+17
| | | | | | | | | | | | | | | | | 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.
* docs(todo): close the roam-inbox batchCraig Jennings13 hours1-8/+31
| | | | | | Eight tasks from the 2026-07-09 roam sweep, each with what landed and where. The signal-count task turned out to be a semantics bug rather than a counting one, and the session-identifier task was tmux, not waybar.
* feat(installer): enable the CPU-mode restore unitCraig Jennings13 hours1-1/+6
| | | | | | | | maint-epp-restore.service replays the remembered energy-performance preference at login, since the kernel resets it to the driver default on every boot. It hangs off default.target rather than timers.target; systemctl --user can't run during install, so the enablement symlink is created directly, the same idiom the scan timers already use.
* docs: move the host inventories into the org-roam knowledge baseCraig Jennings13 hours8-931/+207
| | | | | | | | | | | | | | | | | | | | 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.
* chore(todo): archive completed and cancelled tasksCraig Jennings19 hours2-234/+233
|
* fix(guard): consume the override sentinel as it's honoredCraig Jennings34 hours2-2/+28
| | | | One touch buys exactly one transaction. The maintenance console's forced live update sets the sentinel and clears it afterward, but a caller that dies mid-update would leave the file behind and keep the guard disarmed until reboot. The hook now deletes the sentinel at the moment it honors it, so a missed cleanup costs nothing. The env override is unchanged, and the caller's clear step stays as the belt-and-suspenders for transactions the hook never fires on.
* fix(maint): uncurate /etc/ssl/private — it was a real misconfigCraig Jennings37 hours1-1/+3
| | | | pacman warned filesystem 755 vs package 700 on both hosts: a world-listable private-key directory, not runtime hardening as the previous commit claimed. pacman never resets existing directory permissions, so I chmod'd 700 on ratio and velox and removed the curation entry. Integrity reads an honest zero on both.
* chore(maint): curate runtime perm drift out of the integrity countCraig Jennings37 hours1-0/+13
| | | | | | Reinstalling the owning packages reset these eight paths and the system re-drifted every one before the next -Qkk read: cupsd rewrites its three conf files mode 600, StateDirectory re-chowns /var/lib/passim on service start, tmpfiles re-groups /var/log/journal inside the reinstall transaction itself, /etc/ssl/private sits hardened below the packaged mode, and the utempter setgid helper carries ownership drift. They would count as integrity findings forever with no action that clears them. All eight are universal Arch runtime behavior, so they ship as qkk_known defaults rather than per-host curation. The utempter entry also silences a content change on that one binary, noted inline and accepted. I installed the TOML on both hosts; integrity now reads zero on each, with the real findings the metric surfaced along the way fixed for real (a stale hyprland.pc on both hosts, and /root sitting world-listable at 755 on velox, restored to the packaged 750).
* fix(guard): allow same-version reinstalls through the live-update hookCraig Jennings37 hours2-15/+128
| | | | | | | | The hypr-live-update-guard hook blocked on target names alone, so a same-version reinstall of hyprland (the maintenance console's integrity REINSTALL, right after a full update) aborted identically to a real upgrade. A pure reinstall writes identical bytes over identical bytes and can't crash the live compositor: the SIGABRT hazard needs the on-disk version to actually change. The guard now compares each target's installed version (pacman -Q) against the sync-db candidate (expac -S %v). Both are read-only queries and safe under the transaction lock, pinned live with db.lck present. Targets that match pass as reinstalls, and the block message lists only the version-changing packages. Unresolvable versions (AUR targets, -U transactions, expac missing) still block conservatively. Verified live on ratio: the previously blocked six-package reinstall ran clean with Hyprland up. The block path is pinned by the test suite (13 tests, four new). I deployed the script to /usr/local/bin on both hosts by hand since the installer only copies it on fresh systems.
* chore(maint): retire cve_min_warn from the thresholdsCraig Jennings38 hours1-3/+3
| | | | The maint probe now grades CVE advisories on actionability (a fixed release exists and isn't installed), not severity, so the severity floor is dead config. The section comment records the retirement. I installed it on both hosts.
* fix(install): mark pacman packages explicit after --needed installCraig Jennings39 hours2-1/+101
| | | | | | pacman --needed skips a package that is already on the system as a dependency and leaves its install reason alone. A declared package can then sit as asdeps, surface as an orphan once its accidental dependent leaves, and get swept away by an orphan cleanup. expac and lm_sensors, both maintenance-console runtime deps, nearly went this way: they were asdeps on both hosts and only survived today's orphan sweep because something still depended on them. pacman_install now marks the package explicit after a successful install. The mark never runs on a failed install, and a mark failure never fails the install. I flipped expac and lm_sensors to explicit on ratio and velox by hand since the installer only runs on fresh systems.
* docs(maint): reword coredump window comment for past-window gradingCraig Jennings40 hours1-1/+4
|
* chore(todo): file retention-repair GUI gap taskCraig Jennings42 hours1-0/+5
|
* fix(maint): add timeline_slack key to the snapshot thresholdsCraig Jennings42 hours1-0/+3
| | | | This pairs with the maint probe change: the snapper grade now warns at summed limits + snapshots.timeline_slack. Slack 2 absorbs the hourly create/:45-cleanup timer gap that kept the card amber most of every hour. I installed it on both hosts.
* fix(maint): raise pacman cache warn threshold to 20GBCraig Jennings42 hours1-1/+2
| | | | | | The 10GB threshold sat below the keep-3 steady state on both hosts (ratio 12.6GB, velox 10.8GB after pruning), so the warning persisted with nothing left to clean. paccache keeps three versions per package and never expires by age, which puts the honest ceiling near 17-19GB. At 20GB the metric stays quiet in steady state but still fires within about two months if the paccache timer dies. I installed it on both hosts and the warning cleared on each.
* chore: health-check updates (workflow note, audit stamp, todo entries)Craig Jennings43 hours3-2/+7
|
* chore: close maintenance-console build, flip spec to IMPLEMENTEDCraig Jennings44 hours2-10/+12
|
* docs: adopt system-health-check workflow and host inventoriesCraig Jennings44 hours6-0/+1948
| | | | | | | | 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.
* feat(install): install maintenance thresholds and enable maint timersCraig Jennings44 hours2-1/+75
| | | | | | | | The maint console and the system-health-check workflow grade against ~/.config/archsetup/maintenance-thresholds.toml, but nothing installed it. A fresh install got a working maint CLI and no thresholds file. user_customizations now installs the shipped TOML from the cloned repo. A re-run refreshes it, and the user layer in ~/.config/maint/ is never touched, so a reinstall can't eat curation. It also enables maint-scan.timer and maint-net-scan.timer through wants-symlinks (systemctl --user has no session bus during install, the syncthing idiom). Timer enablement is hyprland-only because the units live in that stow tier. The install lists gain the runtime tools the probes call but nothing carried: expac, lm_sensors, fwupd.
* chore: close build Phase 12 in todo, file zfs DKMS image bugCraig Jennings44 hours1-2/+5
|
* test(maint): add VM and nspawn remedy scenario harnessCraig Jennings44 hours13-1/+1138
| | | | | | Nine break/fix/assert scenarios run the real maint fix inside the test VM. The runner batches non-conflicting scenarios into one VM boot, restores the snapshot only between groups, and leaves the base image pristine afterwards. A systemd-nspawn fast lane runs the pacman-level group against a cached pacstrap rootfs in seconds. The plan layer validates the scenario contract without a VM and carries a 19-test unit suite. make test-maint wires the VM lane in. The zfs lane is filtered but unexercised: the FS_PROFILE=zfs base image fails to build (ZFS DKMS module not found on linux-lts 6.18). The failure is tracked in the todo.
* chore: log maint refactor sweep in todoCraig Jennings45 hours1-0/+3
|
* chore: close build Phase 11b in todoCraig Jennings46 hours1-2/+3
|
* chore: close build Phase 11, add fidelity phase 11bCraig Jennings47 hours2-2/+9
|
* chore: close build Phase 10 in todoCraig Jennings48 hours1-2/+3
|
* chore: close build Phase 9 in todoCraig Jennings2 days1-2/+3
|
* chore: log build Phase 9a in todoCraig Jennings2 days1-1/+4
|
* chore: close build Phase 8 in todoCraig Jennings2 days1-2/+3
|
* chore: close build Phase 7 in todoCraig Jennings2 days1-2/+2
|
* chore: close build Phase 6 in todoCraig Jennings2 days1-2/+2
|
* feat: Phase 6 threshold keys (update guard, session-critical, quarterly)Craig Jennings2 days1-0/+24
| | | | [updates] guard_patterns is the live-update guard's pattern set (mesa/hyprland/wayland runtime plus both hosts' vulkan drivers); [curation.session_critical] is the KILL lever's denylist; timeline_quarterly completes the snapper set-config key set.
* chore: close build Phase 5 in todoCraig Jennings2 days1-2/+2
|
* feat: Phase 5 threshold keys (network, backups, services)Craig Jennings2 days1-0/+8
|
* feat: Phase 4 threshold keys (logs, memory, power)Craig Jennings2 days2-2/+14
|
* feat: Phase 3 threshold keys, arch-audit dep, btrfs scrub timerCraig Jennings2 days3-2/+39
| | | | | | The thresholds TOML gains packages.keyring_warn_days, the [security] cve_min_warn floor, [systemd] expected_timers_extra, and two curation tables: kept_orphans (deliberate keeps the orphan count skips) and qkk_known (fnmatch paths for -Qkk mismatches that are config knowledge, like the resolver symlink and the pacman-contrib file this script edits itself). The installer now pulls arch-audit (the console's CVE source) and enables btrfs-scrub@-.timer on btrfs installs. Ratio had the scrub timer enabled out-of-band, so a fresh install would have warned "missing" forever on the console's maintenance-timers check. The todo Phase 3 task closes as a dated log entry.
* feat: storage threshold keys + close build Phase 2Craig Jennings2 days2-2/+8
| | | | The TOML gains the Phase 2 storage bands (btrfs unallocated floor, SMART wear/temp, fstrim staleness, top-consumers scan knobs). Collectors shipped in dotfiles; installed copies refreshed on ratio and velox.
* feat: seed maintenance-thresholds.toml + close build Phase 1Craig Jennings2 days2-2/+89
| | | | | | The TOML carries every severity value the console and the system-health-check workflow grade against (the workflow's hard-won numbers: the 10 GB cache trigger, the 35/60-day scrub bands, the snapper TIMELINE limits from the 2026-05-26 /home lesson) plus the shipped curation defaults. Canonical home is configs/ here. Installer wiring stays Phase 13, so for now the file is hand-copied to ~/.config/archsetup/ on ratio. Phase 1 of the build landed in dotfiles (43a39ac): maint package skeleton, two-layer thresholds engine, capability probe, and the status contract with three pilot collectors, 48 tests. The todo phase task flips to its dated log entry.
* docs: maintenance-console spec to DOING + build decompositionCraig Jennings2 days2-2/+399
| | | | | | 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.
* docs: add maintenance console design + interactive prototypesCraig Jennings2 days11-0/+5679
| | | | | | | | 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.
* docs: PTT waybar-indicator prototypeCraig Jennings3 days1-0/+133
| | | | | | | 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.
* docs: per-device activity lamp shipped (audio metering option 3)Craig Jennings4 days2-2/+15
| | | | 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.
* docs: audio-panel signal-metering spec (implemented)Craig Jennings4 days2-8/+268
| | | | 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.
* docs: archive shipped panel-bug batch; track system-monitor design captureCraig Jennings4 days2-16/+1023
| | | | 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.