max / mountaineer
1 file changed,
+24 insertions,
-20 deletions
| @@ -89,7 +89,7 @@ Lives in `../build/`. **Full installer runs end-to-end in QEMU as of build 16**; | |||
| 89 | 89 | - [ ] **Framework 13 hardware test**: `dd` `out/mountaineer-server-v3.23-x86_64.iso` to USB, boot F13 in UEFI mode, run installer against `/dev/nvme0n1` (triggers the `p1`/`p2` partition-naming branch in `installer/install.sh`). If F13 needs wifi setup before install: `iwctl` in the live env. | |
| 90 | 90 | - [ ] Re-verify the install → reboot → ssh-in cycle in QEMU with build 16 (the new ISO carries the kcl-property + pubkey fixes that haven't yet been exercised end-to-end together). | |
| 91 | 91 | - [ ] First-boot route walk-through: ROUTES.md "first boot" beyond hostname (network up, operator key works, services up under s6-rc) — verify each. | |
| 92 | - | - [ ] Reproducible builds: build 16 from a clean checkout twice, compare sha256 of the ISO. | |
| 92 | + | - [ ] Reproducible builds: static audit landed in `../build/build_notes.md` (apkovl half looks reproducible by construction; ISO half has 8 candidate non-determinism sources). Next concrete step is the apkovl-only diff (`build-apkovl.sh` twice, compare sha) before spinning the VM. Requires GNU tar on the build host. | |
| 93 | 93 | ||
| 94 | 94 | ### Build history — fixes burned through (institutional memory) | |
| 95 | 95 | ||
| @@ -186,7 +186,7 @@ Builds 11–16 (ISO-boots-and-installs era — full session details in `../build | |||
| 186 | 186 | ||
| 187 | 187 | ### Per-subcommand implementation | |
| 188 | 188 | ||
| 189 | - | Status: MVP slice complete. `sysop info`, `sysop motd`, `sysop services`, `sysop storage`, `sysop wifi`, `sysop net` all run on host via mock-or-real backend auto-detection. Yambar producers ready for `svc`, `zfs`, `net`. `sysop wifi` is the first interactive subcommand (masked password input). Active: TBD — natural next is `sysop id` (large) or overlay/installer work in `../build/`. | |
| 189 | + | Status: MVP slice complete plus the follow-ups previously deferred. `sysop info` now ships version display + server/sysadmin profile filter. `sysop net` shows default-route + resolver liveness. `sysop wifi` auto-detects the interface, pre-scans, rescans on `r`, and has a `disconnect` verb. `sysop storage` has a pool detail screen (`zpool status -P` parsing) and a dataset view (`d`). All `--summary` outputs unchanged. Active: TBD — natural next is `sysop id` (large) or live-system verification on a Mountaineer install. | |
| 190 | 190 | ||
| 191 | 191 | **sysop-tui primitives** | |
| 192 | 192 | ||
| @@ -196,13 +196,15 @@ Status: MVP slice complete. `sysop info`, `sysop motd`, `sysop services`, `sysop | |||
| 196 | 196 | ||
| 197 | 197 | **sysop info** | |
| 198 | 198 | ||
| 199 | - | - [ ] Version field on the detail screen (requires per-tool version queries — shell out to `<tool> --version`, parse, cache; defer until subprocess plumbing is settled) | |
| 199 | + | - [x] Version field on the detail screen — lazy per-tool `<bin> --version` lookup with per-session cache; populated for 18 of 30 roles via `version_cmd` in roles.toml | |
| 200 | + | - [x] Server vs Sysadmin profile filter — `--server` / `--sysadmin` flags filter via the `profile` field on Role (12 graphical roles tagged `sysadmin`) | |
| 200 | 201 | - [ ] Runtime override: layer `/etc/mountaineer/roles.toml` on top of the compiled-in defaults (principle 2 — operator can see/edit). Currently only `include_str!` source | |
| 201 | - | - [ ] Server vs Sysadmin profile filter — graphical-layer roles should be hidden in `--server` mode | |
| 202 | + | - [ ] Fill `version_cmd` for the remaining roles (busybox, s6, ifupdown-ng, iwd, cliphist, swaybg, swappy, seatd, tlp) — most need a tool-specific incantation | |
| 203 | + | - [ ] Replace synchronous Command::output with a bounded-timeout variant if any version_cmd is found to hang on a real Mountaineer system | |
| 202 | 204 | ||
| 203 | 205 | **sysop motd** | |
| 204 | 206 | ||
| 205 | - | - [ ] `/etc/profile.d/sysop-motd.sh` glue script — calls `sysop motd print` on login. Lives in `../build/apkovl-src/` | |
| 207 | + | - [x] `/etc/profile.d/sysop-motd.sh` glue script — calls `sysop motd print` on login (silent no-op if sysop missing). Lives in `../build/apkovl-src/common/` | |
| 206 | 208 | - [ ] Tip set worth revisiting once more `sysop` verbs exist — currently 6, drawn from AESTHETICS | |
| 207 | 209 | - [ ] Decide whether `sysop motd print` should respect a "first-login-of-the-day" suppression to avoid tip spam in tmux-heavy sessions | |
| 208 | 210 | ||
| @@ -215,26 +217,25 @@ Status: MVP slice complete. `sysop info`, `sysop motd`, `sysop services`, `sysop | |||
| 215 | 217 | ||
| 216 | 218 | **sysop storage** | |
| 217 | 219 | ||
| 218 | - | - [ ] Detail view: vdev tree, error counters (read/write/cksum), scrub progress. Needs `zpool status -P <name>` parsing | |
| 219 | - | - [ ] Dataset view: `zfs list` — separate verb (`sysop storage datasets`?) or filtered detail screen | |
| 220 | + | - [x] Detail view: vdev tree, error counters (read/write/cksum), scrub progress — `zpool status -P <name>` parsing with indent-preserving vdev tree, scan/errors lines, per-row red error counts | |
| 221 | + | - [x] Dataset view: `zfs list -H -o name,used,avail,mountpoint` — `d` key from pool list opens it; `Esc` returns | |
| 220 | 222 | - [ ] Snapshot management — read-only first (list), write later | |
| 221 | 223 | - [ ] Scrub trigger verb. Same caveat as services enable/disable — gate on live system | |
| 222 | 224 | ||
| 223 | 225 | **sysop wifi** | |
| 224 | 226 | ||
| 225 | - | - [ ] Pre-scan: `iwctl station wlan0 scan` + brief wait before `get-networks`, so the cache is fresh on first invocation | |
| 226 | - | - [ ] `r` to rescan from the list view (calls iwctl scan, waits, refreshes) | |
| 227 | - | - [ ] Auto-detect interface name (currently hardcoded `wlan0`); `iwctl device list` is the source | |
| 227 | + | - [x] Pre-scan: `iwctl station <dev> scan` + 1.5s settle before `get-networks`; `r` rescans from the list view with "scanning…" indicator | |
| 228 | + | - [x] Auto-detect interface name from `iwctl device list` (mode=station), fall back to `wlan0` | |
| 229 | + | - [x] Disconnect verb — `sysop wifi disconnect` | |
| 228 | 230 | - [ ] Enterprise (8021x) flow — out of scope for MVP, currently a no-op on Enter; needs identity + cert/PEAP plumbing | |
| 229 | 231 | - [ ] iwctl `get-networks` text parsing is fragile; verify on a real Mountaineer install and adjust. D-Bus interface is the upgrade path if the text format proves too noisy | |
| 230 | - | - [ ] Disconnect verb (`sysop wifi disconnect`) | |
| 231 | 232 | - [ ] Promote the password input to a `sysop-tui` primitive once a second consumer exists (probably `sysop id` for passphrase entry) | |
| 232 | 233 | ||
| 233 | 234 | **sysop net** | |
| 234 | 235 | ||
| 236 | + | - [x] Default route / gateway display — `ip -json route show default` parsing, rendered as a header row above the interface list | |
| 237 | + | - [x] Resolver liveness check — 200 ms TCP probe to 127.0.0.1:53 (`reachable` / `unreachable`), rendered alongside default-route | |
| 235 | 238 | - [ ] SSID enrichment for wireless: read `/var/lib/iwd/` or `iwctl station <iface> show` to populate `ssid` on the real backend (mock already returns it) | |
| 236 | - | - [ ] Default route / gateway display (`ip -json route show default` parsing) | |
| 237 | - | - [ ] Resolver liveness check — show whether unbound is reachable on 127.0.0.1:53 (would also feed a future `sysop info resolver` detail screen) | |
| 238 | 239 | - [ ] Yambar `net` segment should reflect the active default-route interface, not just wired-first. Currently wired-first heuristic | |
| 239 | 240 | - [ ] Detail view: per-interface MAC, MTU, link speed (ethtool for wired) | |
| 240 | 241 | ||
| @@ -284,16 +285,19 @@ Status: MVP slice complete. `sysop info`, `sysop motd`, `sysop services`, `sysop | |||
| 284 | 285 | - [x] `sysop info <role>` — first subcommand, role→tool registry shipped (33 roles in `../sysop/crates/sysop/data/roles.toml`) | |
| 285 | 286 | - [x] `sysop motd on/off/print` — opt-out tip rotation, time-bucketed; config at `/etc/mountaineer/sysop.toml` (`$SYSOP_CONFIG` override for host dev) | |
| 286 | 287 | - [x] `sysop services` (read-only) — s6-rc backend with mock fallback for host dev; `--summary` emits `ok`/`N down` for the yambar `svc` segment to consume. Enable/disable verbs deferred to live-system phase | |
| 287 | - | - [x] `sysop storage` (read-only) — zfs backend (zpool list) with mock fallback; `--summary` emits `ok`/`degraded` for the yambar `zfs` segment. Detail view, scrub trigger, snapshot ops deferred | |
| 288 | - | - [x] `sysop wifi` — iwctl backend with mock fallback. Selection + password prompt + connect attempt; first interactive subcommand (masked input). Enterprise (8021x), pre-scan, rescan, disconnect, auto-iface deferred | |
| 289 | - | - [x] `sysop net` — iproute2 backend (`ip -json addr show`) with mock fallback. Interface list with state + addresses + SSID; `--summary` for the yambar `net` segment (`eth0 ↑` / `wlan0 <ssid>` / `net ↓`). Default-route awareness, gateway display, resolver liveness check deferred | |
| 290 | - | - [ ] Overlay configs in flatwhite + Iosevka: foot, helix, zellij, fuzzel, fnott, swaylock, yambar — apkovl-src work | |
| 288 | + | - [x] `sysop storage` — zfs backend with mock fallback; pool list + detail (vdev tree, error counters, scrub line) + dataset view (`d` from pool list). `--summary` emits `ok`/`degraded` for the yambar `zfs` segment. Scrub trigger and snapshot ops deferred | |
| 289 | + | - [x] `sysop wifi` — iwctl backend with mock fallback. Auto-iface, pre-scan, rescan, disconnect, selection + masked password + connect. Enterprise (8021x) deferred | |
| 290 | + | - [x] `sysop net` — iproute2 backend with mock fallback. Default-route + resolver liveness header rows; interface list with state + addresses + SSID; `--summary` for the yambar `net` segment. SSID enrichment, detail view deferred | |
| 291 | + | - [x] Overlay configs in flatwhite + Iosevka: foot, helix (theme), zellij (theme), fuzzel, fnott, swaylock — `../build/apkovl-src/sysadmin/` | |
| 292 | + | - [x] yambar config: tag + clock + bat + net + vol + svc + zfs segments; svc/zfs/net feed scripts at `usr/local/libexec/yambar/{svc,zfs,net}.sh` calling `sysop <subcmd> --summary`. Conditional `vpn`/`dnd` still to add | |
| 293 | + | - [x] `/etc/issue` content set to spec form (`Mountaineer 3.23 (Dull Edge) · \n · \l`); version literal needs a bump when Alpine base moves | |
| 294 | + | - [x] `/etc/profile.d/sysop-motd.sh` — shim calling `sysop motd print`; silent no-op if sysop missing | |
| 291 | 295 | - [ ] river init: minimal active bind set + commented-available blocks from upstream example — apkovl-src path TBD | |
| 292 | - | - [ ] yambar config: tag + date/time/bat/net/vol/svc/zfs segments, conditional `vpn`/`dnd`; Mountaineer-specific `svc` (s6-rc) and `zfs` data sources need scripts | |
| 293 | - | - [ ] `/etc/issue` content (`Mountaineer 3.21.0 (Dull Edge) · \n · \l`) — apkovl-src work | |
| 294 | - | - [ ] `/etc/profile.d/sysop-motd.sh` — one-line shim that calls `sysop motd print` on login (apkovl-src) | |
| 296 | + | - [ ] Activate the `sysadmin` manifest profile (`sources = ["common", "live", "sysadmin"]`, separate `world` file) so the new overlay tree actually ships | |
| 295 | 297 | - [ ] `/etc/mountaineer/sysop.toml` seed with `[motd] enabled = true|false` written by installer based on Y/n prompt | |
| 296 | 298 | - [ ] Installer prompt: "Show a `sysop` tip on each login? [Y/n]" → writes motd-enable choice into the seed file above | |
| 299 | + | - [ ] Conditional yambar segments: `vpn wg0` and `dnd` (notifications muted) — need state probes | |
| 300 | + | - [ ] Version-pump discipline for `/etc/issue` — emit from build.sh into apkovl-src as a generated file, or accept hand-bump per Alpine release | |
| 297 | 301 | ||
| 298 | 302 | ## Project / community | |
| 299 | 303 |