fix(pkgs): one chromium, not two — and what that is actually worth
All checks were successful
Check / eval (push) Successful in 3m32s

BACKLOG #121. nixpkgs' chromium wrapper with enableWideVine = true (what the
template ships, for DRM) runs the `-wv` copy but links its share/* from the
PLAIN unwrapped build. A symlink is a store reference, so a second 687 MiB
chromium rode along for a directory of .desktop files nothing executes.
overlays.default now points those symlinks at the copy we already run; the
template needs no change, since lib.nix, the repo pkgs and nixosModules all
apply the overlay.

Checked first, because it decided whether the item was possible at all:
whether the `-wv` copy references the plain build. It is `cp -a` of it, so it
plausibly would have — and then no wrapper change could have dropped the
duplicate. It does not. Also verified rather than assumed: `.override
{ enableWideVine = true; }` composes with the overlay's overrideAttrs (the
order usually matters), so the template's existing line picks the fix up
untouched; the wrapper still execs the -wv build with WidevineCdm present; and
share/{applications,icons,man} match stock with the .desktop byte-identical.

I claimed this was "687 MiB off every install". It is not, and measuring the
artifact instead of the closure is what corrected it:

    nominal closure          -687 MiB  (9.38 -> 8.71 GiB)
    ISO image                -8 KiB    of 8.078 GiB
    installed disk           ~-19 MiB
    cache-install download   -195 MiB

Two dedupes that closure arithmetic cannot see. mksquashfs detects duplicate
files, so the ISO had already stored the near-identical blocks once. And
auto-optimise-store (on by default here) hardlinks identical files: the two
paths share inodes — verified by stat, and du counts 639 MiB for the pair
against ~620 for one. The only thing that cannot dedupe is the wire, where the
extra path is its own 195 MiB NAR.

So this is a DOWNLOAD fix — precisely what #120's netinstall cares about — and
close to a no-op for the offline ISO that is the default today. Whether that
justifies coupling an overlay to nixpkgs wrapper internals is Bernardo's call;
it is guarded and no-ops if upstream moves, but it is his to weigh. Worth an
upstream patch regardless: the wrapper should take its desktop entry from the
variant it wraps.

The guard is the load-bearing part, because the failure mode is a SILENT no-op
that no build complains about: checks.chromium-single-closure asserts exactly
one full unwrapped chromium in the template closure, and was proved to fail by
neutering the overlay — it reports "found 2", names both paths, and warns off
the tempting "fix" of dropping enableWideVine, which silently removes DRM.

The rule this establishes, now recorded in ROADMAP and on #120 (whose entire
size table is closure arithmetic): closure size is not disk size and is not
image size. Measure the artifact.

V2: flake check, chromium-single-closure, live-baseline-apps, template-sot,
option-docs, state-bridges all pass. Three ISOs built from one tree for the
numbers above.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 17:26:24 +01:00
parent 00b1e10fc3
commit 0b464af3e5
4 changed files with 194 additions and 34 deletions

View File

@@ -176,17 +176,34 @@ and ship a **much lighter netinstall variant alongside it**. Two products, one
distro: "works on a plane" and "8 GiB is absurd to download" are both true, and
a second target settles them without compromising either.
**Measured facts (2026-07-14), so this starts from numbers, not vibes:**
**Measured facts (2026-07-14), so this starts from numbers, not vibes.**
*(Taken before #121 landed; it removed a duplicate 687 MiB chromium, so the
uncompressed figures below are each ~0.67 GiB lower now — the live desktop is
**13.34 GiB**, not 14.01. The shape of the argument is unchanged. Re-measure
before acting rather than trusting these.)*
> **Read this before using the numbers below.** They are **closure arithmetic**,
> and #121 proved the hard way that closure size is neither disk size nor image
> size: removing a 687 MiB path shrank the ISO by **8 KiB**, because
> **mksquashfs dedupes duplicate files** and **`auto-optimise-store` hardlinks**
> them on disk. So a change that looks like it sheds gigabytes of closure can
> shed nothing off the actual image. **Measure the artifact — build the ISO and
> `stat` it.** The corollary cuts the other way and is the good news for this
> item: what dedupe cannot help is the **wire**, so a netinstall's download is
> the one figure closure/NAR size predicts honestly (`nix path-info --store
> https://cache.nixos.org --json` gives the real `downloadSize`).
- Current ISO **8.078 GiB** compressed; **18.03 GiB** of store uncompressed
(`zstd -19`, 2.23:1 — compression is already near-max, not the lever).
- The offline pin (`system.extraDependencies`, 60 roots: a representative
installed system + the template HM closure + all flake inputs) is **4.02 GiB
uncompressed of that — only ~22%**. Dropping it entirely still leaves a
**14.01 GiB** desktop → roughly **6.3 GiB** compressed at the same ratio.
**~13.3 GiB** desktop → roughly **6 GiB** compressed at the same ratio.
**So "no pin" alone is NOT the lighter ISO** — this is the trap to avoid.
- The 14 GiB desktop's own top weights: libreoffice 1457 MiB, initrd 1369,
linux-firmware 770, chromium ×2 (1391 combined — see #121), llvm-lib 540,
- The desktop's own top weights: libreoffice 1457 MiB, initrd 1369,
linux-firmware 770, chromium 704 (was 1391 before #121), llvm-lib 540,
bibata-cursors 322, mesa 264, mbrola-voices 259, nerd-fonts ~420 combined.
Note what that list implies: no single lever gets a desktop ISO under ~4 GB —
which is the case for (b) below.
**So the real decision is what a netinstall ISO IS**, and it should be settled
first (`[human]`): (a) the full try-before-install desktop minus the pin
@@ -211,36 +228,6 @@ the measured number, both ISOs built from one tree), installs successfully with
a network in a QEMU run, says clearly at boot that it needs one, and leaves the
offline ISO's behaviour untouched (`checks.*` for the offline path stay green).
### 121. The Widevine chromium wrapper drags a second 687 MiB chromium along
Found while measuring #103 (2026-07-14). **Pre-existing and not live-only**
it is in the template HM closure, so it is on **every installed Nomarchy
machine** and in the ISO, and predates #103 by however long chromium has been
the default browser.
`templates/downstream/home.nix` ships `chromium.override { enableWideVine =
true; }` (correctly — DRM for Netflix/Spotify). The resulting wrapper depends on
**two** unwrapped builds:
704 MiB chromium-unwrapped-150.0.7871.114-wv ← the browser it runs
687 MiB chromium-unwrapped-150.0.7871.114 ← plain build, pulled in for
`share/applications` ONLY
`nix why-depends --precise` on the live closure shows the wrapped
`chromium-…/share/applications` symlinking into the *plain* unwrapped output,
which retains the whole 687 MiB derivation for a directory of `.desktop` files.
Nothing runs it.
Investigate whether this is a nixpkgs wrapper bug (the wrapper should take its
desktop entry from the same variant it wraps) — fix upstream and/or work around
it locally, but **verify the fix by closure diff, not by reading the
expression**: `nix path-info -r <hm-generation> | grep chromium-unwrapped`
should list one full build plus the small sandbox. Do **not** "fix" it by
dropping `enableWideVine` — that silently removes DRM playback, which is a
feature decision (ROADMAP § Default application suite), not a size cleanup.
Pass = one full chromium in the closure, DRM still works (V3: a Widevine page
plays on hardware), and the measured install/ISO delta is recorded.
### 115. Suspend-then-hibernate, with a way to set it up
Bernardo, 2026-07-14: a suspended laptop should be able to fall through to