Skip to main content

max / alloy_tui

docs: stub todo to GoingsOn pointer; build reference moved to wiki Task tracking lives in the GoingsOn `alloy` project. The QEMU boot findings and v0 stack manifest moved to the private code wiki (alloy-build-notes).
Co-Authored-By
Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-15 12:49 UTC
Signed with PGP, not checked
Commit: 07fb4c37b6c5af731a751b18d33892a009ce58c4
Parent: 94ec7ac
1 file changed, +5 insertions, -129 deletions
M docs/todo.md +5 -129
@@ -1,131 +1,7 @@
1 - # Alloy todo
1 + # todo
2 2
3 - ## Open questions to resolve
3 + Work for Alloy lives in GoingsOn (project `alloy`), not here. Add and track tasks
4 + there; this file is only a pointer.
4 5
5 - - [ ] XDG icon theme for *adopted* apps (cosmic-files, file managers, MIME-type icons): build, adopt cosmic-icons, or pull from a standard set? Authored apps already covered by [ICONOGRAPHY.md](ICONOGRAPHY.md) — this question is only about icons consumed by third-party Linux apps that read `XDG_ICON_THEME`.
6 - - [ ] cosmic-notifications under Niri: verify whether it runs cleanly enough to be the v0/v1 daemon (would be more Rust-aligned than mako).
7 -
8 - ## Pre-v0 work
9 -
10 - - [ ] Validate the dark-mode L stops against measured WCAG contrast on a calibrated display (deferred from TOKENS.md).
11 - - [ ] Audit Departure's unicode coverage; document the fallback chain (Iosevka) for out-of-range code points.
12 - - [ ] Branding assets: wordmark/logotype, repo social card, favicon. Deferred until first user-facing surface ships.
13 - - [x] Push Alloy to `git.sr.ht/~maxmj/alloy`. Repo auto-created on first push; `srht` remote tracking `main`.
14 - - [x] First green build of `Containerfile` (build + lint only, no distribution yet). Built `alloy:local` on fw13 from `fedora-bootc:42`; 7.77 GB image; 10 lint checks passed, 3 warnings (informational — flatpaks in /var).
15 -
16 - ## Follow-up build work
17 -
18 - - [x] Multi-stage cargo-install build for Rust tools without published Fedora packages: `ironbar`, `anyrun`, `wl-screenrec` in one `rust-build` stage; **Gram** (Zed fork) in its own `gram-build` stage per todo's build-weight note. Both stages land on `registry.fedoraproject.org/fedora:42`; binaries copied to `/usr/local/bin` in the runtime stage. Runtime libs (gtk3/gtk4 + layer-shell, ffmpeg-free, vulkan-loader/mesa-vulkan-drivers) added to the runtime dnf install. anyrun pulled `--git` (not on crates.io); ironbar and wl-screenrec pulled from crates.io. First rebuild will validate; if wl-screenrec turns out to be git-only, flip that one line to `--git https://github.com/russelltg/wl-screenrec`.
19 - - [x] Address bootc lint's `/var` warnings — moved Flatpak provisioning (flathub remote-add + Floorp/Rnote install) to `usr/lib/systemd/system/alloy-flatpak-firstboot.service`, a first-boot oneshot with `ConditionPathExists=!/var/lib/alloy/flatpak-firstboot.done`. Enabled via `etc/systemd/system-preset/50-alloy.preset`. Build-time Flatpak lines removed from the Containerfile.
20 - - [x] Boot the image in a VM (`bootc-image-builder` → qcow2 or ISO) to verify it actually runs as an OS beyond just linting clean. Booted 2026-07-04 on fw13 via `podman run … bootc-image-builder:latest build --type qcow2 --rootfs xfs …`, then `qemu-system-x86_64 -enable-kvm -machine q35` with OVMF. Kernel + initrd + systemd all clean; tuigreet reached VT1 after the fixes below were applied by hand in the running VM. Punch list captured under "Punch list from first QEMU boot" below.
21 - - [x] Package Alloy-authored config files that STACK.md references but the Containerfile doesn't yet ship. Shipped 2026-07-05 under `etc/skel/.config/`: `niri/config.kdl`, `ironbar/{config.toml,style.css}`, `anyrun/{config.ron,style.css}`, `rio/config.toml`, `yazi/{yazi.toml,theme.toml}`, `mako/config`, `satty/config.toml`, `swaylock/config`, `starship.toml`. All applied Alloy light-mode palette per docs/TOKENS.md and IosevkaTerm Nerd Font per docs/STACK.md#fonts. Live-system verification pending — see the follow-up item below.
22 - - [ ] Live-system verification of the packaged configs. Test on Framework 13 (or QEMU with hardware passthrough where feasible): rio → yazi kitty-graphics preview, Niri Fn-key binds → swayosd overlays, Print → screenshot to `~/Pictures/Screenshots/`, Mod+Print → satty on latest, Mod+Ctrl+L → swaylock with palette, ironbar workspaces reflecting Niri IPC, anyrun launcher, mako urgency colors, starship prompt on nu login. Any config that breaks on real hardware gets fixed and re-shipped as a follow-up.
23 -
24 - ## Punch list from first QEMU boot (2026-07-04)
25 -
26 - All five items are Containerfile bugs uncovered by actually booting the image. Reproducer for each is "boot the vanilla `alloy:local` qcow2, observe." All landed and verified 2026-07-04 by rebuilding `alloy:local`, regenerating the qcow2 with no CLI overrides, and booting: greetd is `enabled` from first boot, `active (running)`, PAM session opens for `greeter`, tuigreet renders on the Alloy palette with no kernel printk overlay.
27 -
28 - - [x] **Declare a default root filesystem.** bootc-image-builder aborts with `missing required info: DefaultRootFs` unless `--rootfs` is passed. Shipped as `usr/lib/bootc/install/00-alloy.toml` with `[install.filesystem.root] type = "xfs"`. Verified by rebuilding the qcow2 without `--rootfs` on the CLI.
29 - - [x] **Apply presets at build time.** `50-alloy.preset` is copied into `/etc/systemd/system-preset/` but nothing was running `systemctl preset-all` during the build, so greetd stayed disabled at first boot even though the preset said enable. Fix: `RUN systemctl preset-all` in the Containerfile immediately after `COPY etc/` / `COPY usr/`.
30 - - [x] **Single-line `etc/greetd/config.toml` command.** The multi-line basic string with backslash continuations tripped greetd's TOML parser (`expected equals sign on line, but found none`). Rewritten as a single-line `command = "tuigreet …"` with the Alloy theme preserved on the same line. Verified by observing the correct palette in the second-boot screenshot.
31 - - [x] **Create the `greeter` system user.** Greetd exits `error: configured default session user 'greeter' not found` without it — Fedora bootc's minimal user database doesn't include it. Added `RUN useradd -M -r -s /sbin/nologin greeter` to the Containerfile. Landed as a system user (uid < 1000). The `video` group also isn't in the base image; not needed for the greetd path, revisit when niri actually needs GPU nodes.
32 - - [x] **Silence kernel `printk` on the greeter VT.** Audit lines from `systemd-hostnamed` and `user-runtime-dir` were overwriting the greeter UI. Shipped `usr/lib/bootc/kargs.d/10-alloy.toml` with `kargs = ["quiet", "loglevel=3"]`. Verified — `/proc/cmdline` in the fresh image includes both flags, and the second-boot screenshot has a clean greeter frame.
33 -
34 - ## New findings from the second QEMU boot (2026-07-04)
35 -
36 - Surfaced during verification of the fixes above; separate work items.
37 -
38 - - [x] **Ship a default `/etc/hostname`.** Shipped as `etc/hostname` with `alloy`. Static for now; if per-install randomization becomes desirable later, replace with a first-boot systemd unit that writes a randomized suffix.
39 -
40 - ## Meta findings from the same session
41 -
42 - Not Containerfile issues, but worth capturing so the next person doesn't rediscover them.
43 -
44 - - **bootc-image-builder must find the source image in the same podman storage it uses.** `sudo podman run … bootc-image-builder … localhost/alloy:local` fails with `image not known` if the image was built rootless. Either build the image as root (`sudo podman build`), or shuttle it across with `podman save localhost/alloy:local | sudo podman load`. The current builder image no longer pulls sources; the error message says so explicitly.
45 - - **First QEMU launch parameters that worked**, for reference: `qemu-system-x86_64 -enable-kvm -cpu host -smp 4 -m 4096 -machine q35 -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd -drive if=pflash,format=raw,file=OVMF_VARS.fd -drive if=virtio,file=disk.qcow2,format=qcow2 -netdev user,id=n0,hostfwd=tcp:127.0.0.1:2222-:22 -device virtio-net-pci,netdev=n0 -vga virtio -vnc 127.0.0.1:1 -serial mon:stdio`. UEFI + q35 is required (bootc images do not have a legacy BIOS path). `hostfwd` for port 22 makes remote diagnosis trivial once sshd is up.
46 -
47 - ## When distribution starts
48 -
49 - Deferred until Alloy has something worth pulling. Re-add `sign` and `push` tasks to `.builds/alloy-image.yml` and populate the sr.ht secrets when doing this.
50 -
51 - - [ ] Provision `quay.io/alloy` org and robot credentials for CI.
52 - - [ ] Populate sr.ht secrets: quay.io robot token, cosign private key.
53 - - [ ] Generate cosign keypair; commit `cosign.pub`, keep `cosign.key` in the sr.ht secret.
54 - - [x] Repackage all `configs/*/` into `etc/skel/.config/*`, `etc/*`, and `usr/share/alloy/*` layout the Containerfile expects.
55 - - [x] Write systemd presets files (`etc/systemd/system-preset/50-alloy.preset` and `etc/systemd/user-preset/50-alloy.preset`) with the defaults per IMAGE.md and CONTINUITY.md.
56 - - [x] Draft `etc/os-release` skeleton (name, ID, URLs pointing at sr.ht, vendor = Make Creative). Full branding (wordmark, logo, plymouth) still deferred.
57 - - [ ] Verify `bootc-image-builder` produces a working installer ISO from the image.
58 -
59 - ## Hardware target: Framework 12
60 -
61 - Full context in [HARDWARE-FW12.md](HARDWARE-FW12.md). Concrete work items below.
62 -
63 - - [ ] **`alloy-hinged` (Rust user daemon).** Reads `SW_TABLET_MODE` transitions; on fold, `niri msg action focus-workspace notes` (spawning Rnote fullscreen if not present); on unfold, `focus-workspace previous`. Single-purpose. ~100 LOC target. Ships as a systemd user service.
64 - - [ ] Reserve a named `notes` workspace in `niri.kdl` defaults.
65 - - [ ] Package Rnote in the v0 stack; set autosave defaults; document as the fold-to-notes app.
66 - - [ ] Verify whether the FW12 kernel auto-suppresses physical keyboard and trackpad on `SW_TABLET_MODE`; if not, add a libinput toggle to `alloy-hinged`.
67 - - [ ] Validate fractional 1.25x scale on the FW12 panel with real egui apps (audiofiles is the closest existing test surface).
68 - - [ ] Prototype fprintd challenge/response loop in an immediate-mode UI — required before v1 egui lockscreen is called done.
69 - - [ ] Measure s2idle drain baseline on FW12 running the Alloy image; decide whether Alloy ships any power tweaks or leaves it to Fedora defaults.
70 -
71 - ## v0 stack to package and document
72 -
73 - Curated install of the C/non-Alloy-authored picks, with default configs:
74 - - Niri (`niri.kdl` defaults including screenshot keybinds)
75 - - Ironbar (default modules + Alloy-flavored theme)
76 - - swaylock
77 - - anyrun (curated plugin set)
78 - - mako (default config)
79 - - satty (annotation defaults)
80 - - yazi (preview/plugin defaults, kitty-graphics previews via rio)
81 - - cosmic-files (Flatpak or layered?)
82 - - rio (TOML config, kitty-graphics enabled)
83 - - Floorp (Flatpak; Alloy `user.js` + `userChrome.css` from `usr/share/alloy/floorp/`)
84 - - nushell as login shell + starship prompt (`etc/skel/.config/nushell/`); bash unchanged at `/bin/sh` and `/bin/bash`
85 - - helix (`etc/skel/.config/helix/` — Alloy Flatwhite theme, `EDITOR=hx` set by nu env; TUI editor for $EDITOR contexts)
86 - - Gram (graphical editor per STACK.md; needs cargo-install stage — see "Follow-up build work")
87 - - mpv (`etc/skel/.config/mpv/`)
88 - - imv (`etc/skel/.config/imv/`)
89 - - zathura (`etc/skel/.config/zathura/`)
90 - - bottom (`etc/skel/.config/bottom/`; `top = btm` alias in nu)
91 - - dua (no config; `du = dua interactive` alias in nu)
92 - - cliphist (no config; `wl-paste --watch` spawn lines in `niri.kdl` startup)
93 - - wl-screenrec (no config; `screenrec` nu function in aliases.nu)
94 - - swayosd (`etc/skel/.config/swayosd/`; systemd user service + niri.kdl Fn-key binds)
95 - - playerctl (no config; niri.kdl media-key binds)
96 - - gammastep (`etc/skel/.config/gammastep/`; systemd user service)
97 - - Bibata Modern Classic cursor (`etc/skel/.icons/default/`; also declared in GTK settings.ini + XCURSOR env vars)
98 - - adw-gtk3 + Alloy palette patch (`etc/skel/.config/gtk-3.0/`, `etc/skel/.config/gtk-4.0/`)
99 - - IosevkaTerm Nerd Font (mono) + Atkinson Hyperlegible (sans) via `etc/skel/.config/fontconfig/fonts.conf`
100 - - greetd + tuigreet (`etc/greetd/`; systemd-enabled by default in the image)
101 - - restic (no config, no default policy; shipped in the base image for users to configure per CONTINUITY.md)
102 -
103 - ## v1 deliverables
104 -
105 - - [ ] egui design-system crate v1 (palette, type, themed widgets, extension traits).
106 - - [ ] Lockscreen (egui, ext-session-lock-v1, marquee app #1).
107 - - [ ] Package GUI (egui, marquee app #2 — pedagogical wedge).
108 - - [ ] **Alloy Console** — see [CONSOLE.md](CONSOLE.md). `alloy` binary with `net`/`audio`/`display`/`update`/`hinged`/`tail`/`sync` subcommands, plus `alloy config <path>` schema-driven TOML/KDL editor. Requires `alloy_tui` crate. v0.5 ships `alloy config` alone with schemas for the v0-adopted configs; full subcommand set at v1.
109 - - [ ] **Continuity stack** — see [CONTINUITY.md](CONTINUITY.md). Package Tailscale client + Syncthing user daemon in the base image, both disabled at first boot. First-boot flow (single screen, two rows) at v1 sits over `alloy tail` / `alloy sync` enrollments.
110 -
111 - ## Pre-stabilization revisits
112 -
113 - - [ ] **Lockscreen crash recovery.** v1 ships relying on Niri's existing fallback when the lock client dies. Before stabilizing, evaluate: (a) Niri's actual fallback behavior — does the user get stranded or does the compositor offer something? (b) watchdog / systemd `Restart=on-failure` supervisor as a v1.x add-on, (c) crash-to-greeter handoff if a Rust greetd-shaped path makes sense. See [`crates/alloy_lockscreen/README.md`](../crates/alloy_lockscreen/README.md) open question #4 for the deferred context.
114 -
115 - ## v2+
116 -
117 - - [ ] egui notification daemon (marquee app #3).
118 - - [ ] Bar in egui (eventual).
119 -
120 - ## v3+ candidates
121 -
122 - - [ ] **`cast`** — Figma plugin / Rust CLI that reads color styles, text styles, spacing, and radii from an Alloy design file in Figma and emits `tokens.toml`. ~2-week scope if the Figma file is structured for export. See [COMPONENT-LIBRARY.md](COMPONENT-LIBRARY.md#late-term-figma--tokens-and-maybe-more). Only meaningful once a designer is actually in the loop.
123 - - [ ] Possible follow-on: static `impl Widget` skeleton generation from Figma frames (narrower than imagined; only works for constrained component patterns).
124 -
125 - ## Late-term research
126 -
127 - - [ ] **`crucible`** (working name) — a design tool native to immediate-mode UI. Component as unit of work, token-first authoring, live render against sample data, composition grammar as the engineer-facing artifact. See [RESEARCH-IMMEDIATE-MODE-DESIGN.md](RESEARCH-IMMEDIATE-MODE-DESIGN.md). v4+ at earliest; its own sibling project if pursued. The architectural prereqs for keeping this door open are already in [COMPONENT-LIBRARY.md](COMPONENT-LIBRARY.md).
128 -
129 - ## Decisions log
130 -
131 - See [STACK.md](STACK.md) and [COSMIC.md](COSMIC.md). When a decision changes, update the doc and note the change in commit history rather than maintaining a separate changelog.
6 + Design detail lives in the sibling docs (STACK.md, TOKENS.md, ICONOGRAPHY.md,
7 + CONSOLE.md, CONTINUITY.md, COMPONENT-LIBRARY.md, RESEARCH-IMMEDIATE-MODE-DESIGN.md).