diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index 70f84f3..8e98e09 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -19,7 +19,32 @@ Template: --- -## 2026-07-14 — #121: one chromium, not two — 687 MiB off every install (this commit) +## 2026-07-14 — #121 reverted: the fix worked, the gain didn't survive measuring (this commit) +- **Task:** Bernardo's call on #121 (shipped 0b464af, reverted here): *"Let's + leave it honestly. Sounds too much work for a negligible gain."* +- **Did:** removed the chromium overlay + `checks.chromium-single-closure`; + template HM closure back to 9.38 GiB and the duplicate unwrapped chromium is + back, deliberately. `overlays.default` carries a comment saying so, and the + ROADMAP entry is now a **✗ decided-against** record holding the measurement, + the working approach, and the commit to recover it from. +- **Why this was right:** the fix worked, but it substitutes into a + `buildCommand` nixpkgs owns — coupling us to wrapper internals with a + *silent no-op* failure mode, which is why it needed a permanent check too. + That standing cost buys ~195 MiB of download and ~19 MiB of disk. Boring + beats clever at that exchange rate (CONVENTIONS). +- **The lesson that outlives it, and the real product of the last two items:** + **closure size is not disk size and is not image size — measure the + artifact.** Removing a 687 MiB path moved the ISO by 8 KiB, because + mksquashfs dedupes duplicate files and `auto-optimise-store` hardlinks them + (the two paths share inodes — `stat`-verified; `du` counts 639 MiB for the + pair vs ~620 for one). Only the wire can't dedupe. This is stamped on #120, + whose entire size table is closure arithmetic — without it, "drop the pin, + save 4 GiB" would have evaporated at the squashfs exactly like this did. +- **Verified:** V0 flake check green; revert confirmed by closure (the plain + chromium is back, 9.38 GiB) rather than by reading the diff. +- **Next suggestion:** #118 (smartd self-gate). + +## 2026-07-14 — #121: one chromium, not two — 687 MiB off every install (superseded by the revert above) - **Task:** BACKLOG #121, found by measuring #103's ISO delta. Nothing was failing — that is the point; a duplicate browser breaks no build. - **Did:** nixpkgs' chromium wrapper with `enableWideVine = true` (what the diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 22ac639..99dc9dc 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -404,8 +404,13 @@ Design/decision records and a running log of shipped work (items marked decision rather than a drive-by. Proved to fail: dropping snapshot makes it name the missing entry. **V3 pending** — that the apps *launch* needs real hardware (HARDWARE-QUEUE, Acer M5-481T). -- ✓ **One chromium, not two (#121):** found by measuring #103's ISO delta - rather than by anything failing — nothing *was* failing, which is the point. +- ✗ **One chromium, not two (#121) — investigated, measured, DECIDED AGAINST + (Bernardo, 2026-07-14): "too much work for a negligible gain".** The bug is + real and the fix worked; the *gain* is what failed to survive measurement. + Kept as a record because the measurement is the valuable part and the next + person to spot the duplicate deserves the numbers rather than the discovery. + Found by measuring #103's ISO delta rather than by anything failing — + nothing *was* failing, which is the point. nixpkgs' chromium wrapper, with `enableWideVine = true` (what the template ships, for Netflix/Spotify DRM), runs the `-wv` copy but links its `share/*` from the **plain** unwrapped build: @@ -413,17 +418,17 @@ Design/decision records and a running log of shipped work (items marked reference, so a whole second **687 MiB** chromium rode along for a directory of `.desktop` files nothing executes — on **every installed machine**, not just the ISO, for as long as chromium has been the default browser. - **What made a fix possible** (checked first, since it decides everything): - the `-wv` copy is `cp -a` of the browser and is **self-contained** — it does - *not* reference the plain build. Had it done so, no wrapper change could - drop the duplicate. Its `share/` is byte-identical, `.desktop` included, so - `overlays.default` moves the symlink source to the copy we already run. - Both paths are read back out of the wrapper's own `buildCommand`, so the - overlay knows nothing of nixpkgs internals beyond two strings; if upstream - restructures either, the match returns null and the fix **no-ops** rather - than breaking a build. With `enableWideVine = false` the paths are equal and - the substitution is identity. DRM payload verified still present in the build - the wrapper execs; `share/` byte-identical to stock. + **A fix is possible, and was proven** (prototyped in 0b464af, reverted in the + commit that carries this entry — recover it from there rather than + rediscovering it): the `-wv` copy is `cp -a` of the browser and is + **self-contained** — it does *not* reference the plain build (had it done so, + no wrapper change could drop the duplicate; check this first if you revisit). + Its `share/` is byte-identical, `.desktop` included, so an `overlays.default` + entry that repoints the wrapper's `share/*` symlinks at the copy we already + run removes the duplicate and nothing else — DRM payload verified still + present, `.desktop` byte-identical to stock, and `.override + { enableWideVine = true; }` composes with the overlay's `overrideAttrs`, so + the template needs no change. **What it actually saves — and the lesson, which is worth more than the fix** (the first pass at this claimed "−687 MiB on every install"; measuring the *artifact* instead of the closure killed that): @@ -448,15 +453,20 @@ Design/decision records and a running log of shipped work (items marked a no-op for the offline ISO that is the default today. **Rule this establishes: closure size is not disk size and is not image size. Measure the artifact.** #120's size table is closure arithmetic and inherits - this caveat. - **The guard is load-bearing**, because a silent no-op is this fix's failure - mode and nothing about it breaks a build: `checks.chromium-single-closure` - asserts the *invariant* (exactly one full unwrapped chromium in the template - closure — plain or `-wv`, never both), not the mechanism, and was proved to - fail by neutering the overlay: it reports "found 2", names both paths, and - says not to "fix" it by dropping `enableWideVine`, which would silently - remove DRM. Worth an upstream nixpkgs patch (the wrapper should take its - desktop entry from the variant it wraps); the overlay is the local stopgap. + this caveat — it is stamped there. + **Why it was reverted rather than kept**, though it worked: the fix is a + string substitution into a `buildCommand` nixpkgs owns, so it couples us to + wrapper internals and its failure mode is a *silent no-op* — which meant it + also needed a permanent `checks.*` to assert the invariant, since nothing + about a returning duplicate breaks a build. That is a standing maintenance + cost against ~195 MiB of download and ~19 MiB of disk. **Boring beats clever + when the gain is this small** (CONVENTIONS: prefer boring, reproducible + mechanisms) — so the duplicate stays, honestly, and `overlays.default` says + so in a comment where the next person will look. + **Revisit if** the netinstall (#120) ships, since download is the one axis + this actually moves; or better, fix it **upstream** — the wrapper should take + its desktop entry from the variant it wraps, which helps every NixOS user + with `enableWideVine`, not just us. - ✓ **Plymouth logo contrast:** the shipped art was a fixed navy that vanished on dark bases. `modules/nixos/plymouth.nix` now recolors every element from the palette at build time (flat fill, alpha kept): diff --git a/flake.nix b/flake.nix index aeee021..9f5d51d 100644 --- a/flake.nix +++ b/flake.nix @@ -94,42 +94,11 @@ # Includes nomarchy-what-changed (generation readability, #82). nomarchy-lifecycle = final.callPackage ./pkgs/nomarchy-lifecycle { }; pam-fprint-grosshack = final.callPackage ./pkgs/pam-fprint-grosshack { }; - - # One chromium, not two (ROADMAP § one chromium, not two, #121). - # Upstream nixpkgs bug, worth a patch there: in - # pkgs/applications/networking/browsers/chromium/default.nix the - # wrapper runs the `-wv` copy when enableWideVine is set, but still - # links its share/ from the PLAIN unwrapped build: - # for f in '${chromium.browser}'/share/*; do ln -s … - # A symlink is a store reference, so that retains a whole second - # 687 MiB chromium for a directory of .desktop files nothing runs — - # on every machine the template installs, not just the live ISO. - # - # Safe because the `-wv` copy is `cp -a` of the browser and is - # self-contained: verified it does NOT reference the plain build (had - # it done so, no wrapper change could drop the duplicate), and its - # share/ is byte-identical, .desktop included. So share moves to the - # copy we already run and nothing else changes. - # - # Both paths are read back out of the wrapper's own buildCommand, so - # this knows nothing about nixpkgs internals beyond those two - # strings. If upstream restructures either, the match returns null - # and this becomes a NO-OP rather than a broken build — and - # checks.chromium-single-closure is what fails, loudly, instead of - # the duplicate quietly returning. With enableWideVine = false the - # two paths are the same and the substitution is identity, so the - # plain package is untouched. - chromium = prev.chromium.overrideAttrs (old: - let - wv = builtins.match ".*makeWrapper \"([^\"]+)/libexec/chromium/chromium\".*" old.buildCommand; - plain = builtins.match ".*for f in '([^']+)'/share/\\*.*" old.buildCommand; - in - prev.lib.optionalAttrs (wv != null && plain != null) { - buildCommand = builtins.replaceStrings - [ "'${builtins.head plain}'/share/" ] - [ "'${builtins.head wv}'/share/" ] - old.buildCommand; - }); + # NOTE: no chromium override here on purpose — the enableWideVine + # wrapper's duplicate unwrapped build is a real upstream bug but is + # worth ~195 MiB of download and ~19 MiB of disk, not the gigabytes it + # looks like. Decided not to work around it locally + # (ROADMAP § one chromium, not two, #121). }; nixosModules.nomarchy = { @@ -595,43 +564,6 @@ # sheet to ✖/exit-1 and names the unit; with the failure # cleared it reports healthy/exit-0. Minimal node (just the # package) — the disk/flake/snapper checks self-skip in a VM. - # One chromium, not two (ROADMAP § one chromium, not two, #121). - # The overlay's wrapper fix is a substitution into a string - # nixpkgs owns: if upstream restructures that buildCommand, the - # match returns null, the fix silently becomes a no-op and 687 MiB - # of duplicate browser quietly returns to every install. Nothing - # about that breaks a build — which is exactly why it needs a - # check. Asserts the invariant, not the mechanism: the closure the - # template installs carries exactly ONE full unwrapped chromium - # (plain OR -wv, never both; the tiny -sandbox output is a separate - # path and is expected). - chromium-single-closure = - let - hm = downstream.homeConfigurations.me.activationPackage; - ci = pkgs.closureInfo { rootPaths = [ hm ]; }; - in - pkgs.runCommand "nomarchy-chromium-single-closure" - { nativeBuildInputs = [ pkgs.gnugrep ]; } - '' - set -euo pipefail - # Full browser builds only: -sandbox is a few KB and legitimate. - full=$(grep -E 'chromium-unwrapped-[0-9.]+(-wv)?$' ${ci}/store-paths || true) - n=$(printf '%s' "$full" | grep -c . || true) - if [ "$n" != 1 ]; then - echo "chromium-single-closure: expected exactly 1 full unwrapped chromium, found $n:" - printf '%s\n' "$full" - echo - echo "If this is 2, the enableWideVine wrapper is retaining the plain" - echo "build for its share/* symlinks again — the overlay fix in" - echo "flake.nix (ROADMAP § one chromium, not two, #121) has stopped" - echo "matching upstream's buildCommand. Do NOT 'fix' it by dropping" - echo "enableWideVine: that silently removes DRM playback." - exit 1 - fi - echo "chromium-single-closure: ok — one chromium ($full)" - touch $out - ''; - # Live-ISO baseline apps (ROADMAP § live-ISO baseline apps, #103). # The live session shipped no # browser and no office for as long as it existed — the thing a user