aboutsummaryrefslogtreecommitdiff
path: root/docs
Commit message (Collapse)AuthorAgeFilesLines
* feat(gallery): add R16 entry keypad, a composed instrumentCraig Jennings12 hours1-0/+45
| | | | | | R16 is the first composed card: a display window, an indicator lamp pod, and a 4x3 key grid working as one instrument. Digits fill the amber display (dim dashes for empty positions), the top lamp lights while the buffer holds anything, the amber check key confirms and the amber cross key clears with a lamp flash. The keycaps are worn gray with per-key numeral jitter, after an industrial keypad prop (reference filed in the catalogue's working directory). I verified the flow in headless Chrome: digits append, confirm reports the code and empties the buffer, clear flashes the lamp, no console exceptions.
* docs(gallery): stop counting widgets in the mastheadCraig Jennings12 hours1-1/+1
| | | | The count went stale twice in one session. The masthead now names the batches without a number.
* feat(gallery): add R14 spade-pointer knob and R15 multi-band dialCraig Jennings12 hours1-0/+84
| | | | | | | | | Two radio-receiver widgets as inline SVG, after a 1920s GE receiver panel and a Hallicrafters shortwave dial pair: - R14 spade-pointer tuning knob: a knurled bakelite knob carries a bright spade pointer over a 0-10 scale rendered as engraved relief (each mark drawn with a light offset twin, ink-free like the source panel). The knurl ring turns with the knob. - R15 multi-band dial: four nested band arcs on a cream face read by one long needle; the active ring draws bold and the rest fade. Dragging the main dial tunes within the active band's frequency range, and clicking the bandspread dial steps bands, turning its own needle. I verified both in headless Chrome: the spade knob tracks drags, tuning moves the needle and readout, the band click switches range and re-weights the rings, no console exceptions. The gallery is at 68 cards.
* feat(gallery): add R12 chrome slot fader and R13 edgewise strip meterCraig Jennings12 hours1-0/+71
| | | | | | | | | Two more reference-batch widgets as inline SVG, from channel-strip references (the fader's source screenshot is filed in the catalogue's working directory): - R12 chrome slot fader: a chrome T-handle with a conical nose rides a recessed slot, the signed dB scale (+12 to -24) engraved on a screwed-down plate. Drag; the readout shows signed dB. - R13 edgewise strip meter: a parchment vertical scale with the compressed log spacing of a gain-reduction meter (0/3/6/12/20/40), a dark bar riding its edge. Drag-driven. I verified both in headless Chrome: handle and bar track drags with correct dB interpolation, no console exceptions. The gallery is at 66 cards.
* feat(gallery): add R08-R11 from hi-fi and cockpit referencesCraig Jennings12 hours1-0/+128
| | | | | | | | | | | Four more reference-batch widgets as inline SVG, from pasted hardware references (a hi-fi chrome level window, aviation instrument clusters, and a vintage altimeter): - R08 chrome MIN/MAX indicator: polished ring, brushed metal dome, cog hub, dark pointer sweeping MIN to MAX. - R09 black-face aviation gauge: amber ticks and numerals on black, painted green/amber/red zone arcs per the airspeed-indicator scheme, glowing amber needle. - R10 data matrix readout: a lit amber data block with labeled fields; click cycles SYS/NET/TIME pages, and the TIME page runs off the real clock. - R11 warning flag window: a striped barber-pole slides into the window when tripped, the mechanical alarm idiom as distinct from a lamp. I verified all four in headless Chrome: both meters track drags, the pages cycle, the flag trips and clears, no console exceptions. The gallery is at 64 cards.
* feat(gallery): add R05-R07 filter bank, chicken-head selector, round meterCraig Jennings13 hours1-3/+100
| | | | | | | | | | | | Three more reference-batch widgets as inline SVG, from the Berna-style faceplate set: - R05 filter slider bank: eight band faders with teal double-arrow caps on black tracks, frequency labels up top, a dB rail at the side. Per-band drag; the readout names the band and its attenuation. - R06 chicken-head selector: the tapered lever aims at the engraved position (OFF/LO/MID/HI); the active legend lights. Click steps through. - R07 round panel meter: porthole black bezel, cream dial, printed dB arc with red zone, drag-driven needle. R07 shares the VU-law dB interpolation with R01 through a new vuDb helper, so the nonlinear scale lives in one place. I verified all three in headless Chrome: band drags update cap and readout, the selector steps and relights, the meter needle tracks drags, no console exceptions. The gallery is at 60 cards.
* feat(gallery): add reference batch R01-R04 modeled on period hardwareCraig Jennings13 hours1-2/+154
| | | | | | | | | | | I built four widgets as inline SVG (the substrate that ports to svg.el), modeled on 1950s-60s lab and console hardware from the reference photos now filed in the catalogue's working directory: - R01 moving-coil VU meter: cream face, authentic nonlinear dB arc (-20 to +3), red zone, ballistic needle on the live signal. - R02 calibrated vernier dial: rotating tick-ring disc with radial numerals under a fixed hairline, fluted bakelite knob, reads to a tenth. - R03 bat-handle toggle: chrome lever on a hex bushing, snaps ON/OFF with lit legends. - R04 bakelite fluted knob: scalloped skirt, glossy dome, amber index over a printed 0-10 scale. I verified all four in headless Chrome: the VU animates with ballistics, the dial and knob track drags, the toggle throws, no console exceptions. The gallery now carries 57 cards.
* refactor(gallery): rename generated tokens.el to gallery-tokens.elCraig Jennings13 hours4-7/+11
| | | | The generated file declares (provide 'gallery-tokens), but `require` resolves a feature by filename, so as tokens.el it could never load from a load-path. The name now matches the feature. gen_tokens.py, the renderer's load, and the README follow.
* feat(gallery): add svg.el renderer proving the Emacs target, fix gauge ticksCraig Jennings13 hours3-2/+186
| | | | | | | | | | gallery-widget.el is the proof-of-concept Emacs renderer: it reads the generated tokens.el and renders the needle gauge (card 10) as SVG via svg.el. Rasterized through librsvg (the renderer Emacs itself uses), it matches the web card side by side: same arc, ticks, glowing amber needle, half-dome hub, and readout from the same tokens. That closes the riskiest unknown in the three-target plan, so the component pattern can now scale widget by widget. The comparison surfaced a real gallery bug: the web gauge's ticks were invisible. Their transform-origin put the rotation center 40px below the dial, so the rotated ticks landed outside the clipped area. I moved the ticks to the arc's top edge with the origin at the pivot, and all three now show at -60/0/+60. The parseability test caught a second bug: the mono token's font stack carries double quotes, which broke the font-family XML attribute. The renderer swaps them to single quotes. Tests are ERT (tests/gallery-widgets/), covering token resolution, angle math (normal/boundary/error), and the rendered document's structure. make test-unit now runs the elisp suites alongside the python ones, and make test-elisp runs them alone.
* refactor(gallery): extract design tokens to one source for 3 targetsCraig Jennings13 hours5-40/+370
| | | | | | | | | | | | The colors, glows, gradient ramp, and pulse rate were hardcoded literals scattered across ~40 sites in the gallery. Retuning the amber meant a find-and-replace through the whole file. I pulled them into tokens.json as the single source. gen_tokens.py reads that source and emits three targets: web CSS custom properties (into the gallery :root, between markers), waybar GTK @define-color declarations, and an elisp alist for the future svg.el renderer. The three genuinely differ (CSS --vars with rgb-triple glows, GTK @define-color with underscore names, elisp hex alist), which is why one generator beats three hand-maintained copies. The amber hue is defined once, and its glow triples are derived from the hex, so retuning it means editing one line and rerunning the generator. The gallery render is unchanged. I verified it pixel-identical against the prior commit with reduced-motion forced and the live clock masked (diff of 0). Tests cover hex conversion, the three emitters, marker replacement, and idempotency: 27 tests, 100% line coverage, wired into make test-unit.
* fix(gallery): repair broken widgets, standardize pulses, retune to amberCraig Jennings14 hours3-55/+40
| | | | | | | | | | | | | | I wrapped the status-lamp and jewel-pilot indicators in an inline-flex row so they render. Their sub-elements were bare inline spans, so the fixed width/height were ignored and the widgets collapsed to empty stages. The other multi-element widgets already use this pattern. The transport cluster looked dead because the reel spokes were near-black on a near-black reel, so the rotation was invisible. Steel spokes plus one amber index spoke make the spin legible. The button logic was already correct. All pulses now run at 1s ease-in-out. The busy lamp was 0.7s, fast enough to read as a flash rather than a pulse. I marked 1s as the standard cadence so new widgets inherit it. I shifted the gold accent to a warm amber across the tokens, glow colors, and lit gradients together, so nothing stays yellow next to amber. I removed the magic-eye tube, dropped from the instrument-panel design that draws from this gallery. I renamed the file to panel-widget-gallery.html (the living catalogue now, not a dated prototype) and updated the two inbound links.
* feat(gallery): make every widget interactive and add instrument idiomsCraig Jennings23 hours1-115/+839
| | | | Turn the panel widget gallery into a driveable kit. Drag the faders, rotary and concentric knobs, encoder, crossfader, thumbwheel, jog wheel, and the gauge needles; click the switches, keys, DIP bank, keyed switch, transport, radio bank, patch-bay, and lamps. Every card shows a live readout that tracks the control. Adds a batch of new console idioms across controls, meters, and readouts (oscilloscope, EQ bars, strip-chart, split-flap, VFD marquee, annunciator, jewel lamps, tape counter, and more).
* feat(gallery): add rotary selector, slide-rule dial, and tube readoutsCraig Jennings23 hours1-0/+64
| | | | Bring the hi-fi selector and vacuum-tube idioms from the Takuzu design pass into the panel widget kit: a rotary selector, a slide-rule tuner dial, a nixie tube, and a magic-eye tube.
* chore: decompose net + bt doctor specs into build tasks, flip DOINGCraig Jennings34 hours2-4/+6
| | | | | | | | 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.
* docs: take net + bt doctor specs to READY after review roundsCraig Jennings35 hours2-68/+158
| | | | | | | | | | 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.
* docs: record spec-review findings on net + bt doctor specsCraig Jennings35 hours2-0/+43
| | | | | | | | | | 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.
* docs: catalogue net + bt failure modes and draft two doctor expansion specsCraig Jennings36 hours3-0/+815
| | | | | | | | 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.
* docs: fold the failure taxonomy into the input-side specCraig Jennings37 hours1-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: fold the saturation-test findings into the audio taxonomyCraig Jennings37 hours1-0/+52
| | | | | | 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.
* docs: triage the audio failure catalogue into remedy classesCraig Jennings38 hours1-4/+206
| | | | | | 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.
* docs: add the run-time privilege model as a doctor decisionCraig Jennings38 hours1-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: catalogue Linux audio input and output failure modesCraig Jennings40 hours1-0/+190
| | | | | | 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.
* docs: record the second review pass on the input-side specCraig Jennings40 hours1-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 Jennings43 hours1-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 Jennings2 days1-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 Jennings2 days2-0/+329
| | | | | | | | | | | | 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.
* docs: close the audio-doctor spec and its taskCraig Jennings2 days1-9/+15
| | | | | | | | 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.
* docs: close the audio-doctor decisions, spec is READYCraig Jennings3 days1-18/+39
| | | | | | | | | | | | | | | | | 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: correct the audio-doctor spec's timeout claim, close Phase 0Craig Jennings3 days1-8/+13
| | | | | | | | | | | | | | 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 Jennings3 days1-0/+258
| | | | | | | | | | | | | | | | | | | | 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 Jennings3 days7-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: move the host inventories into the org-roam knowledge baseCraig Jennings3 days7-931/+167
| | | | | | | | | | | | | | | | | | | | 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: health-check updates (workflow note, audit stamp, todo entries)Craig Jennings4 days2-2/+2
|
* chore: close maintenance-console build, flip spec to IMPLEMENTEDCraig Jennings4 days1-2/+3
|
* docs: adopt system-health-check workflow and host inventoriesCraig Jennings4 days6-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.
* chore: close build Phase 11, add fidelity phase 11bCraig Jennings4 days1-0/+3
|
* docs: maintenance-console spec to DOING + build decompositionCraig Jennings5 days1-0/+346
| | | | | | 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 Jennings5 days10-0/+5666
| | | | | | | | 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 Jennings6 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 Jennings6 days1-2/+8
| | | | 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 Jennings6 days1-0/+226
| | | | 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 Jennings7 days1-0/+1008
| | | | 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.
* docs(timer): record the shipped redesign and flip spec to IMPLEMENTEDCraig Jennings7 days4-47/+1925
| | | | | | 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.
* docs(todo): timer panel shipped — spec IMPLEMENTED, task closed, manual ↵Craig Jennings7 days1-3/+4
| | | | | | 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.
* docs(spec): timer panel to DOING, fold in the cj-comment build scopeCraig Jennings8 days1-2/+23
| | | | 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.
* docs(spec): fold the wallpaper-manager input into desktop-settings scopeCraig Jennings8 days1-0/+7
| | | | 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.
* docs: gather panel design prototypes into docs/prototypes/Craig Jennings8 days8-3/+2720
| | | | | | 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/.
* docs(spec): restore faceplate design edits to desktop-settings specCraig Jennings8 days1-4/+25
| | | | 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.
* docs(spec): resolve timer and desktop-settings panel decisionsCraig Jennings8 days2-44/+47
| | | | | | 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.
* docs(spec): sort formal specs into docs/specs/ with lifecycle statusCraig Jennings8 days7-0/+42
| | | | 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.