diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-20 21:56:55 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-20 21:56:55 -0400 |
| commit | c7fa7feca46e081641d9a6c3d4f34799b1683b23 (patch) | |
| tree | 6a296841cf6de40211acbb1f0ef2882cb027e74c | |
| parent | 62e45197bb4d440e002b731715343e565cf50ff3 (diff) | |
| download | archsetup-c7fa7feca46e081641d9a6c3d4f34799b1683b23.tar.gz archsetup-c7fa7feca46e081641d9a6c3d4f34799b1683b23.zip | |
chore: document a priority scheme and close two tasks in todo.org
I added an A/B/C/D priority scheme to the task list: what each level means, the assignment criteria, and the rule that an [#A] task needs a scheduled or deadline date so priorities stay grounded in time.
I also closed two finished tasks: the rm -rf path guard (done, with a pointer to the safe_rm_rf helper and its tests) and the touchpad toggle indicator (spec, implementation, and deploy record).
| -rw-r--r-- | todo.org | 75 |
1 files changed, 70 insertions, 5 deletions
@@ -2,7 +2,64 @@ #+AUTHOR: Craig Jennings #+DATE: 2026-02-14 + +* Archsetup Priority Scheme +Four levels, matching the Emacs config (=org-highest-priority ?A=, =org-lowest-priority ?D=, =org-default-priority ?D= in =modules/org-config.el=). Priority answers "how much does this matter"; a date answers "when". They are independent — assign both deliberately. Org priority alone never schedules anything, which is why undated [#A]/[#B] tasks feel ungrounded. + +- [#A] Must happen. Broken install, data loss, security, or a blocker for other work. An [#A] REQUIRES a SCHEDULED or DEADLINE date — if it can't be dated, it isn't really an A; drop it to B. (The main agenda always shows open A's.) +- [#B] Should happen, this cycle. Real improvement or fix with no hard date. Surfaces in the agenda's priority-B block only while undated; add a SCHEDULED date when you commit to a week and it moves into the schedule. +- [#C] Nice to have / someday. Kept for the record, low urgency. Date it only when it graduates to B. +- [#D] Default / unsorted. A bare TODO with no cookie is D. Stays out of the agenda — the inbox of priorities. Triage D's up to A/B/C or let them sit. + +Rule of thumb: A = dated-and-must; B = the active backlog; C = parking lot; D = untriaged. Fixing the undated A/B tasks means either dating them or demoting to C. * Archsetup Open Work +** DONE [#B] toggle key for touchpad on/off +CLOSED: [2026-05-20 Wed] +*** 2026-05-20 Wed @ 18:18:30 -0400 Spec: touchpad toggle + waybar indicator + +**** Current state +A toggle mechanism already exists in the live home dir but is only partly committed. +- =~/.local/bin/toggle-touchpad= (live, NOT in repo): reads/writes a state file at =${XDG_RUNTIME_DIR:-/tmp}/touchpad-state= (values "enabled"/"disabled"), flips =hyprctl keyword "device[$TOUCHPAD]:enabled" true|false=, and fires a =notify info "Touchpad" ...= toast. Hardcodes =TOUCHPAD="pixa3854:00-093a:0274-touchpad"=. +- =~/.local/bin/touchpad-auto= (live, NOT in repo): daemon watching Hyprland's =.socket2.sock= for mouseadded/mouseremoved/configreloaded, auto-disables the touchpad when an external mouse is present, writes the same state file. Same hardcoded device name. +- Keybinding already committed: =bind = $mod, F9, exec, toggle-touchpad= (=hyprland.conf:315=). +- State file confirmed live at =/run/user/1000/touchpad-state= (reads "enabled"). + +**** Gap +1. No waybar indicator — nothing in modules-right shows touchpad state; no =custom/touchpad= module exists. +2. Neither =toggle-touchpad= nor =touchpad-auto= is committed into the repo. They live only in =~/.local/bin=, so a fresh stow won't install them. They belong in =dotfiles/hyprland/.local/bin/= (the =dotfiles/dwm/.local/bin/toggle-touchpad= is the old X11/xinput version, unrelated). +3. =touchpad-auto= is never started — no =exec-once= launches it. +4. The toggle doesn't refresh waybar, so an indicator would lag until its poll interval. + +**** Proposed implementation +1. New status script =dotfiles/hyprland/.local/bin/waybar-touchpad= mirroring =waybar-layout= / =waybar-netspeed= (emit one JSON line: text + tooltip + class). Reads the state file the toggle already writes — single source of truth, no extra hyprctl call. Emits a "disabled" class + off-icon when the state file reads "disabled", else "enabled" + on-icon. +2. Waybar module in =dotfiles/hyprland/.config/waybar/config=, using "signal" so the toggle pushes an instant refresh (no polling — state only changes on toggle or mouse hotplug): + =, "custom/touchpad": { "exec": "waybar-touchpad", "return-type": "json", "signal": 9, "on-click": "toggle-touchpad" }= + Add =custom/touchpad= to modules-right, near =idle_inhibitor=. +3. Refresh-on-toggle: have =toggle-touchpad= (and =touchpad-auto='s set function) run =pkill -RTMIN+9 waybar= after each write to the state file (RTMIN+N ⇄ waybar "signal": N). Alternative: drop "signal", use "interval": 2 (simpler, ~2s lag, constant poll). Signal is the cleaner fit. +4. =style.css= (=dotfiles/hyprland/.config/waybar/style.css=): add =#custom-touchpad= to the shared padding/hover selector lists; add =#custom-touchpad.disabled { color: #d47c59; }= (the dupre orange already used for warnings). Enabled state inherits the default color. +5. Keybinding: keep =$mod+F9= (=hyprland.conf:315=). The waybar on-click gives a mouse path to the same action. +6. Commit the live scripts so stow installs them: =toggle-touchpad= and =touchpad-auto= into =dotfiles/hyprland/.local/bin/= (plus the =pkill= line), and =waybar-touchpad= (new). If the auto-disable-on-external-mouse behavior is wanted at boot, add =exec-once = touchpad-auto= near the other daemon exec-once lines. + +**** Decisions (Craig, 2026-05-20) +1. Icons: enabled / disabled (the mouse / mouse-off pair). +2. Waybar on-click toggles the touchpad. +3. Commit =touchpad-auto= and add its =exec-once= so it runs at login. +4. Signal-driven refresh (=pkill -RTMIN+9 waybar=). +Note: the hardcoded device name =pixa3854:00-093a:0274-touchpad= is Framework-laptop-specific — a portability concern for other machines, not a blocker for this task. + +*** 2026-05-20 Wed @ 18:29:06 -0400 Implemented the toggle + waybar indicator (in repo) +Built per spec + decisions above. Committed the two formerly-live-only scripts into the repo and added the indicator: +- =dotfiles/hyprland/.local/bin/waybar-touchpad= (new) — reads =$XDG_RUNTIME_DIR/touchpad-state=, emits JSON (text/tooltip/class), fail-safe to "enabled". Unit-tested in =tests/waybar-touchpad/= (6 Normal/Boundary cases). +- =dotfiles/hyprland/.local/bin/toggle-touchpad= — copied from =~/.local/bin=, added =pkill -RTMIN+9 waybar= so the indicator refreshes on toggle. +- =dotfiles/hyprland/.local/bin/touchpad-auto= — copied in, =pkill -RTMIN+9 waybar= inside =set_touchpad= so auto on/off events refresh too. Added =exec-once = touchpad-auto= to =hyprland.conf=. +- =waybar/config= — =custom/touchpad= module (signal:9, on-click toggle-touchpad), placed in modules-right before idle_inhibitor. +- =waybar/style.css= — =#custom-touchpad= in padding + hover lists; =.disabled { color: #d47c59 }= (dupre orange). +- =$mod+F9= bind already present (=hyprland.conf=), left as-is. + +*** 2026-05-20 Wed @ 18:36:26 -0400 Deployed + verified on velox +Discovered =.local/bin= is stow-symlinked (waybar-layout/netspeed point into the repo); the two touchpad scripts were real files only because they weren't committed. Replaced both real files with repo symlinks and symlinked the new =waybar-touchpad= (matching the existing relative-symlink form). velox needed no hyprland.conf change — =exec-once = touchpad-auto= and the =$mod+F9= bind were already present. waybar =config= / =style.css= are real local files on velox (config diverges: standalone battery, no sysmonitor group), so applied targeted edits there rather than a copy. + +Verified end-to-end after a waybar restart: config loads with no parse errors; toggle round-trips state enabled → disabled (, class disabled) → enabled (), and the =pkill -RTMIN+9 waybar= refresh fires into the running bar. Touchpad left enabled. Visual confirmation (icon in bar, orange when off) is Craig's to eyeball. Other machines (ratio) pick this up on =git pull && make restow hyprland= — their =.local/bin= and waybar configs are symlinks, so no real-file conflict there. ** DOING [#A] Separate dotfiles from archsetup *** 2026-05-11 Mon @ 13:01:29 -0500 AI Response: Dotfile separation plan Approach: keep =dotfiles/= committed in this repo as the working default (Craig's machines and CI keep functioning untouched), but make the *source location* a config variable. The install script learns one new conf key — =DOTFILES_REPO= / =DOTFILES_BRANCH= — and when set, clones that repo into =~/.dotfiles= and stows from there instead of from =dotfiles/= inside archsetup. The Makefile gets a =DOTFILES= override env var so the same stow targets work whether dotfiles live in-repo or elsewhere. No submodule (adds fragility for a curl|bash installer); a separate published =archsetup-dotfiles= repo is optional follow-up, not a blocker. @@ -25,7 +82,7 @@ Open questions for Craig: *** 2026-05-13 Wed @ 13:07:54 -0500 AI Response: Open questions answered; full spec written All 5 questions resolved: extract now (Q1), clone to =~/.dotfiles= (Q2), no opt-out — =DOTFILES_REPO= always has a default (Q3), include =minimal/= as Tier B with TUI apps (Q4), error out if dotfiles dir isn't a git checkout (Q5). Full spec at [[file:docs/PLAN-dotfiles-separation.org][docs/PLAN-dotfiles-separation.org]] — covers the =minimal/= tree, SSH/GPG availability, three-phase implementation plan (Phase 1: extract + populate new repo at =cjennings.net/archsetup-dotfiles.git=; Phase 2: wire archsetup + VM test; Phase 3: migrate machines + remove =dotfiles/=), commit map, and open observations. Implementation gated on spec review. -*** DONE [#A] Review docs/PLAN-dotfiles-separation.org +*** 2026-05-14 Thu Review docs/PLAN-dotfiles-separation.org CLOSED: [2026-05-14 Thu] Review the spec for accuracy, edge cases, and scope. Flag changes before implementation starts. See [[file:docs/PLAN-dotfiles-separation.org][docs/PLAN-dotfiles-separation.org]]. @@ -51,7 +108,7 @@ Checked each subtask below against the source / git state. Bottom line: almost n - *Dynamic waybar/foot config based on screen resolution* — NOT DONE. No resolution-detection/generation script. - *Bulk shellcheck cleanup* — PARTIALLY DONE. =shellcheck archsetup= still shows 68 findings: 30×SC2329, 16×SC2174, 15×SC2024, 4×SC2086, 1 each SC2155/SC2129/SC2005. The 4 SC2086 (unquoted) are the ones a reviewer would flag — those are the priority. - *Document testing process in README* — NOT DONE. =scripts/testing/README.org= exists but isn't the project README. (Now unblocked — root README exists.) -- *Add guard for rm -rf on constructed paths* — NOT DONE. =archsetup:236= (=rm -rf "$state_dir"=), =:474=, =:939= (=rm -rf "$build_dir"=) have no directory-exists / expected-location check. +- *Add guard for rm -rf on constructed paths* — DONE 2026-05-20. All three constructed-path deletes routed through a =safe_rm_rf= guard (absolute / no-=..= / inside-allowed-prefix / real-dir checks); unit-tested in =tests/safe-rm-rf/=. - *Standardize boolean comparison style* — NOT DONE. Mixed: =[ "$var" = "true" ]= at =archsetup:542,544,569= vs bare =if $var;= form ~7 places elsewhere. - *Replace eval with safer alternatives* — NOT DONE. =archsetup:442= still =if eval "$cmd" >> "$logfile" 2>&1;= in =retry_install=. @@ -153,9 +210,17 @@ Fixed the four that are genuine: =init= (a =#!/bin/sh= script) used =$(</etc/hos *** 2026-05-20 Wed @ 06:32:17 -0500 Documented the testing process in the README The README only covered the VM integration harness; the unit-test layer under =tests/= (Python =unittest=, fake-binary-on-PATH, one dir per script — =layout-navigate=, =tmux-util=) was undocumented. Added a =make test-unit= target that runs every =tests/*/test_*.py= suite explicitly (=unittest discover= can't find them — hyphenated dir names aren't valid package paths), then rewrote the README Testing section into "Unit tests" and "Integration tests (VM harness)" subsections, including how to add a suite for a new script. Updated Contributing to point at =make test-unit= for script changes. 61 unit tests pass via the new target. -*** TODO [#A] Add guard for rm -rf on constructed paths -Lines 236, 466, 905: validate directory exists and is in expected location before =rm -rf=. -cj: you can probably do this on your own +*** 2026-05-20 Wed @ 18:22:42 -0400 Added safe_rm_rf guard on constructed-path deletes +Added a self-contained =safe_rm_rf <path> <allowed_prefix>= helper to =archsetup= and routed all three constructed-path deletes through it. The guard refuses to run unless the target is absolute, free of =..=, deeper than a bare top-level dir, strictly inside the allowed prefix (not the prefix itself), and a real directory (not a symlink); otherwise it prints the reason and returns non-zero without deleting. On the happy path it delegates to =rm -rf=. + +Sites converted (the line numbers in the original task body were stale — actual sites located by grep): +- =--fresh= state-dir wipe — prefix =/var/lib/archsetup=. +- =git_install= clone-retry cleanup (=build_dir= under =$source_dir=). +- =aur_installer= yay clone-retry cleanup (same prefix). + +The helper is defined before the top-level =--fresh= handler (which runs at load time, before the logging helpers exist), so it carries no =error_warn= dependency and reports refusals to stderr itself. The two in-function sites keep their existing =|| error_warn= / =|| error_fatal= handling. + +Tests: =tests/safe-rm-rf/test_safe_rm_rf.py= sources the real function out of the script and exercises Normal/Boundary/Error cases (13 tests) against real temp dirs. =make test-unit= green (61 tests), =bash -n= clean, no new shellcheck warnings. *** TODO [#A] Standardize boolean comparison style Mixed =[ "$var" = "true" ]= vs =$var= evaluation — pick one pattern. |
