| 170 |
170 |
|
- [x] **v1 scope: SSH only** — age and Nebula CA bindings deferred
|
| 171 |
171 |
|
- [x] **Signing-as-a-service is v1 design requirement** — operations split: *use* (sign/decrypt/derive — works on all backends including hardware) vs *extract* (read bytes — best-effort, fails on hardware-backed scopes). v1 must model this even though it only ships software-backed scopes
|
| 172 |
172 |
|
- [x] **SSH-specific shape decided**: `sysop id agent <scope>` returns ssh-agent socket, backends plug behind it (`file://`, `agent://`, `yubikey://` v2). Consumers set `SSH_AUTH_SOCK`. `sysop id sign` for non-ssh-agent cases. `sysop id export` is extract verb (always succeeds on `file://` in v1)
|
| 173 |
|
- |
- [ ] Language confirmed (likely Rust given ratatui)
|
| 174 |
|
- |
- [ ] Repo layout / source-of-truth for role→tool mapping (principle 15)
|
| 175 |
173 |
|
- [ ] Final subcommand list spec'd (sketch: `sysop id list/show/new/import/rotate/authorize/revoke/agent/sign/export`, `sysop id host show/rotate`)
|
| 176 |
174 |
|
- [ ] Reconcile route-assumed subcommands when sysop section opens
|
| 177 |
175 |
|
- [ ] STACK.md: dedicated `sysop` section (currently buried in ifupdown-ng paragraph)
|
| 186 |
184 |
|
- [ ] Hardware key bootstrap: how does `sysop id import --yubikey` work — discover-and-claim, or operator-supplied handle?
|
| 187 |
185 |
|
- [ ] Cross-host scope sync (two laptops): operator's problem (rsync/git) but needs defended recommendation in docs
|
| 188 |
186 |
|
|
| 189 |
|
- |
### Deferred (decided but not v1)
|
|
187 |
+ |
### Per-subcommand implementation
|
|
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/`.
|
|
190 |
+ |
|
|
191 |
+ |
**sysop-tui primitives**
|
|
192 |
+ |
|
|
193 |
+ |
- [ ] Re-verify on a real Mountaineer system (foot terminal, Iosevka, flatwhite-configured 24-bit color). Host-side macOS eyeball passed; values may still need tuning once foot/helix/zellij/yambar ship the matching theme
|
|
194 |
+ |
- [ ] `Footer` right-align option (deferred until a subcommand needs a left status segment)
|
|
195 |
+ |
- [ ] Help overlay primitive (`?` action classifies; no overlay renderer yet)
|
|
196 |
+ |
|
|
197 |
+ |
**sysop info**
|
|
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)
|
|
200 |
+ |
- [ ] 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 |
+ |
|
|
203 |
+ |
**sysop motd**
|
|
204 |
+ |
|
|
205 |
+ |
- [ ] `/etc/profile.d/sysop-motd.sh` glue script — calls `sysop motd print` on login. Lives in `../build/apkovl-src/`
|
|
206 |
+ |
- [ ] Tip set worth revisiting once more `sysop` verbs exist — currently 6, drawn from AESTHETICS
|
|
207 |
+ |
- [ ] Decide whether `sysop motd print` should respect a "first-login-of-the-day" suppression to avoid tip spam in tmux-heavy sessions
|
|
208 |
+ |
|
|
209 |
+ |
**sysop services**
|
|
210 |
+ |
|
|
211 |
+ |
- [ ] Detail view per service: dependencies, log path, time-in-state. Needs `s6-svstat` shell-out
|
|
212 |
+ |
- [ ] Enable / disable / restart verbs. Requires real s6-rc; can't be meaningfully mocked, gate on live-system testing
|
|
213 |
+ |
- [ ] Reflect transient state from `s6-rc-update` runs (currently only Up/Down are derived from `s6-rc -a list` + `-d list`)
|
|
214 |
+ |
- [ ] Backend mismatch indicator — if mock is active on what looks like a Mountaineer system, surface that as a fault
|
|
215 |
+ |
|
|
216 |
+ |
**sysop storage**
|
|
217 |
+ |
|
|
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 |
+ |
- [ ] Snapshot management — read-only first (list), write later
|
|
221 |
+ |
- [ ] Scrub trigger verb. Same caveat as services enable/disable — gate on live system
|
|
222 |
+ |
|
|
223 |
+ |
**sysop wifi**
|
|
224 |
+ |
|
|
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
|
|
228 |
+ |
- [ ] Enterprise (8021x) flow — out of scope for MVP, currently a no-op on Enter; needs identity + cert/PEAP plumbing
|
|
229 |
+ |
- [ ] 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 |
+ |
- [ ] Promote the password input to a `sysop-tui` primitive once a second consumer exists (probably `sysop id` for passphrase entry)
|
|
232 |
+ |
|
|
233 |
+ |
**sysop net**
|
|
234 |
+ |
|
|
235 |
+ |
- [ ] 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 |
+ |
- [ ] Yambar `net` segment should reflect the active default-route interface, not just wired-first. Currently wired-first heuristic
|
|
239 |
+ |
- [ ] Detail view: per-interface MAC, MTU, link speed (ethtool for wired)
|
|
240 |
+ |
|
|
241 |
+ |
### Deferred subcommands (post-MVP)
|
|
242 |
+ |
|
|
243 |
+ |
- [ ] `sysop logs <service>` — lnav front
|
|
244 |
+ |
- [ ] `sysop upgrade`, `sysop wg`, `sysop notifications mute`, `sysop podman-s6`
|
|
245 |
+ |
|
|
246 |
+ |
### sysop tooling deferred (post-MVP)
|
|
247 |
+ |
|
|
248 |
+ |
- [ ] Tab completion (bash/zsh/nushell)
|
|
249 |
+ |
- [ ] Man pages (mdoc; generated from clap?)
|
|
250 |
+ |
- [ ] CI / reproducible builds story
|
|
251 |
+ |
- [ ] Release artifact shape (static-linked musl binary in Alpine apk)
|
|
252 |
+ |
|
|
253 |
+ |
### `sysop id` deferred (decided but not v1)
|
| 190 |
254 |
|
|
| 191 |
255 |
|
- [ ] **Age slot in scopes** + per-host age recipient. Mesh route assumes age-encrypted bundles addressed to per-host recipients; v1-compatible variant needed (operator-decrypted-locally or scp over existing ssh path)
|
| 192 |
256 |
|
- [ ] **Nebula CA slot in scopes**. v1: mesh CA management is its own thing under `~/.config/mountaineer/nebula-ca/`, age-encrypted independently. Reunified when scope model is mature
|