All notable changes to the Margine bootc image build are recorded here.
Image tags follow stable, stable.YYYYMMDD, YYYYMMDD.
Semantic versioning (v0.X.Y) will start once the first user-facing
stable release is cut.
- The public product name is "Margine OS" (fixed together with the DistroWatch submission). os-release NAME/PRETTY_NAME/VERSION/VARIANT now say "Margine OS" (GNOME About, hostnamectl, BLS boot entries), the About panel's Website link points at https://margine.dev (was GitHub), the Archive ISO titles read "Margine OS ... Linux ISO", and README leads with the full name. "Margine" stays as the short form in running text; the technical identifiers (VARIANT_ID=margine for countme, margine-* names, Archive identifiers, the image name) are deliberately unchanged. Naming policy recorded in docs/BRANDING.md.
- Reverse-DNS namespace moved to dev.margine. The last identifiers
derived from the old domain are gone: the ISO-builder GUI app id is now
dev.margine.IsoBuilder(.desktop, D-Bus name, Justfile, DESIGN.md, renamed together), and the never-producedplace.the-empty.margine.kernelstatus label became a realdev.margine.kernelOCI label, stamped at rechunk from the built rootfs, so /status reads the kernel from the image instead of a curated carry-over. The redundantspec-reflabels (equal toorg.opencontainers.image.revisionand dropped by rechunk anyway) are deleted, which finally makes the 2026-07-05 "spec-ref label is gone" changelog claim true. - The project domain is now margine.dev. Every living reference moved over: os-release URLs, margine-status/update, the docs-open helper, the offline-docs mirror source (verified live: 35 pages + 89 assets, zero failures), the CI publishers (status.json, countme.json, ISO date bump), README/SECURITY/issue templates and the spec docs. Historical entries keep the old margine.the-empty.place URLs; a 301 redirect keeps them working.
- Update watchdog +
ujust margine-update-unblock. Extra-data Flatpaks (Reaper) download their real binary from the vendor at update time; flatpak's fetch has no timeout, and a dropped CDN connection wedged the nightly uupd run and the system flatpak lock (Bazaar included) for days, twice in 12 days (2026-06-28, 2026-07-08). The existing 30-min kill only bounded each cycle (and only in awake time: systemd timeouts freeze across suspend), so the retry loop persisted (73 cycles observed). Now uupd's OnFailure= firesmargine-update-watchdog: it identifies the in-flight extra-data app from the journal and, at 2 strikes in 7 days,flatpak masks it so unattended updates complete again. The user gets a session notification andujust margine-update-unblockupdates the app in the foreground and re-includes it. OS updates were never starved: uupd stages the system image before touching flatpaks.
margine-statusno longer lies on systems with a pending update. The layered-deployment fallback readdeployments[0], which is the STAGED deployment, so the tool showed the staged version as "your deployment, up to date" while the machine was running the previous one. It now selectsbooted==true, shows aStaged (applies at next boot)line, a "staged, reboot to apply" verdict, unattended-update health and any watchdog-excluded apps.- Update notifications now actually reach the user. The post-reboot
"Now running: X" toast ran at
default.target(before the session's notification daemon exists) and recorded itself as delivered even when notify-send failed; it also crashed on layered deployments (bootc omitsbooted.imagethere). Moved tographical-session.target, state advances only after a successful notify, rpm-ostree fallback added. The staged- update timer only counted monotonic time (frozen across suspend, so it effectively never fired on a laptop); it now fires on the wall clock (OnCalendar+Persistent=true) and also announces a newly staged deployment right away, once, instead of only nagging after 2 days.
- Reaper is no longer preinstalled (still one click away in Bazaar). Policy: no extra-data apps in the preinstall set; their vendor download is exactly the unattended-update hang above. Existing installs keep Reaper and are protected by the watchdog.
- One repo.
margine-fedora-atomic(the spec: theconfigure-*/validate-*scripts,declarations.yaml, branding assets, ADRs, and the handbook) was merged intomargine-imagewith its full history preserved, then archived read-only. The build no longer fetches anything at build time: scripts and declarations install frombuild_files/40-spec-scripts/, branding frombuild_files/50-branding/assets/, and the spec docs live indocs/spec/.MARGINE_REPO/MARGINE_REF, the build-start "resolve spec ref to SHA" step, the--build-arg MARGINE_REF, and thespec-refOCI label are gone. Every image is now byte-reproducible from the singlemargine-imagecommit it was built from (org.opencontainers.image.revision). This fixes two long-standing problems: forks could not build (CI resolved<owner>/margine-fedora-atomicand 404'd on a fork), and every change used to need coordinated PRs across two repos. The archived companion stays readable at its old URL, so already-installed systems'DOCUMENTATION_URLkeeps resolving.
ujust margine-darktable-openclenables GPU OpenCL in the preinstalled darktable Flatpak via the host Mesarusticldriver (no ROCm/CUDA). Opt-in, idempotent, per-user.ujust margine-reportcollects a diagnostic bundle (image version, hardware, Secure Boot, Flatpak health, this boot's errors) into~/margine-report.txtand opens the GitHub issue chooser, so bug reports land in one searchable place.ujust margine-netflix-1080pinstalls the AMO-signed "Netflix 1080p UA" extension into the Zen Browser profile (opt-in) so Netflix serves 1080p on Linux. Widevine already works on Margine's Zen; this only presents an Opera-on-Linux user agent to Netflix.ujust margine-blender-gputurns on GPU (HIP) rendering in the preinstalled Blender Flatpak on AMD by exposing the host's ROCm runtime (which the Flatpak lacks) to Blender's library path. Verified on a Radeon 760M: a Cycles GPU render completes, no HSA override needed.- /status "Devices running Margine" chart, sourced weekly from Fedora's
public Count Me dataset (Margine ships
VARIANT_ID=margine, so it appears there with no telemetry of our own). - Shared bash history across terminal windows (issue #278): a
/etc/profile.ddrop-in appends each command to the history file and pulls in other sessions' lines, so up-arrow works across multiple Ptyxis windows instead of each keeping a private, clobbered history.
ujust bluefin-cliworks again (issue #291): the branding strip was deleting/usr/bin/ublue-blingtogether with Bluefin's fastfetch binaries, but the inheritedbluefin-clirecipe still calls it, so it failed with "command not found". The bling toggle now stays (only the fastfetch branding is stripped) and the strip validator no longer flags it.- Recycling a test VM no longer deletes the ISO it booted from. Every
margine-test-*teardown (themargine-test-vmrecycle,margine-test-vm-remove,margine-test-vm-clean, the dev Justfile and the ISO-builder GUI) usedvirsh undefine --remove-all-storage, which removes every attached volume including the cdrom ISO. Since rebuilds reuse the sameoutput/Margine-Live.isopath (a session storage pool), re-testing a fresh build deleted it. Teardowns now remove only the VM's writable scratch disks; the GUI also reports a failed VM launch instead of toasting success.
- The offline manual now shows its images. The offline-docs scraper
rewrote page links but never downloaded the referenced assets, so
screenshots, fonts and favicons were blank offline. It now localizes
<img>,srcsetand CSSurl()assets into the mirror (build seed and the runtime refresh both, since they share the scraper). - Security audit remediation. Closed a path-traversal in the offline-docs
scraper (a hostile or MITM'd docs origin could make the root-run build-time
writer place a file outside the mirror); SHA-pinned the grype installer and
the MoreWaita icon fetch, pinned
internetarchivein the IA-credential jobs, added input validation to thescheduler-applypkexec helper, made recipe-argument handling injection-safe ($-exported params, quoting), and removed a stray committed.pycthat shipped into/usr/libexec. - The ISO publish no longer hangs on a wedged upload. The Internet Archive
step used
ia upload, whose retries only fire on error responses, so a dead socket blocked a multi-GB upload until the job timed out. It now uses a stall-awarecurluploader (aborts a transfer that sits under 10 KB/s, retries on a fresh connection, HEAD size+md5 verify so re-runs resume) that also waits out a global Internet Archive rationing event within a wall-clock budget.build-diskconcurrency now queues same-variant dispatches instead of cancelling an in-flight publish.
- Fresh-install Flatpaks were empty on every real install (take 2, reverses
PR #222). The installer baked the default Flatpaks into the bare dedicated
/varbtrfs subvol (/mnt/sysimage/var), but on a bootc/ostree first boot the booted/varis the per-deployment stateroot checkout seeded from the image commit — not that subvol — so the baked repo was lost and everyflatpakop failed (CyberOto, forum 12247).install-flatpaks.ksnow bakes into$deployment.0/var/libviaostree rev-parse … ostree/0/1/0, byte parity with upstream Bluefin/Aurora (which use the same dedicated-/varpartitioning).flatpak-preinstall.servicestays enabled (Margine DEFERs GIMP/Inkscape/darktable/OBS + Reaper to it; Reaper cannot be baked), with arestoreconExecStartPre so a bake-lost fallback can't leave a mislabeled repo stub. The install gate (verify-install-disk.sh) now asserts the bake LOCATION, and thecheck-flatpak-fixes.shregression guard (which had inverted to assert the old target) is corrected.
- EasyEffects now actually starts hidden. The autostart used only
--service-mode, which in EasyEffects 8.x (Qt) still pops the window open at login (user-reported). Add--hide-windowso it starts as a background service with the window closed; re-open it from Activities (it attaches to the running service). Effects stay inert until a preset is enabled.
ujust install-koofr(aliasujust koofr) — installs the Koofr Desktop sync client natively and rootless from upstream's self-updating tarball into~/.koofr-dist(no Flatpak/RPM/Distrobox; never layered, since it auto-updates inside$HOME). Autostarts hidden to the system tray at login via the binary's-silentflag, withsilentStart:truepersisted in~/.koofr/config.jsonas belt-and-suspenders (guarded so it never clobbers a running client); a manual menu launch still opens the window.removeuninstalls the three artifacts and kills the process.ujust margine-test-vm(+margine-test-vm-remove) — throwaway VM to test a Margine ISO on the real secure path: UEFI Secure Boot with Microsoft keys pre-enrolled (so MOK enrollment is exercised) + an emulated TPM 2.0 (for LUKS auto-unlock). Rootlessqemu:///session; an ISO arg boots a ready VM, no arg defines a clone template.- EasyEffects autostarts headless — system
/etc/xdg/autostartentry runs EasyEffects in--service-mode(no window) on login.
- Super+arrows now move the focused window within the o-tiling layout (gaps
preserved) via
tile-move-*-global; the GNOME gapless built-ins that used to eat the chord are cleared. Focus stays on Super+hjkl.
- Plymouth graphical boot on fresh installs and in VMs. Three causes, all
baked into
/usr/lib/bootc/kargs.d/10-margine-plymouth.toml+ the theme: (1) the bootc/titanoboa ISO didn't setrhgb quiet, so fresh installs booted to a text console with the LUKS prompt amid kernel logs — nowrhgb quiet. (2) The real blocker in VMs: the installer addsconsole=ttyS0(the guest has a serial device), which Plymouth treats as headless and so it skips the graphical splash entirely — nowplymouth.ignore-serial-consoles. Plymouth then renders via the EFI framebuffer (efifb, built-in); no extra GPU module in the initramfs is needed (an attempt to forcevirtio_gpuin was dropped — it was unnecessary and the build container's dracut wouldn't resolve it anyway). (3) The early-KMS→real-GPU mode switch mid-boot left the wordmark + LUKS prompt off-centre — the theme now re-centres the logo and the dialog on a resolution change (margine.scriptrefresh_callback). The theme itself was never at fault; the host (no serial console, real GPU) was unaffected throughout. - o-tiling gap defaults now actually apply.
gap-inner/gap-outer(and the active-hint border radius/width) areuint32keys, but the dconf default wrote them as bare ints (gap-inner=2), which the db stored as int32 — a type mismatch the gschema rejects, so they silently fell back to o-tiling's own defaults (gap 4) on fresh installs (user-reported). Tagged themuint32in03-margine-o-tiling. Also aligned the o-tiling cosmetic defaults with the intended config: title-bar min/max + close buttons on, skip-overview on, workspace-number-indicator on, smart-gaps/snap-to-grid off.
- Safe TPM2-unlock + autologin helpers —
ujust margine-tpm-unlock(status/enable/disable) andujust margine-autologin(status/on/off). The TPM helper is lockout-proof by construction: auto-detects the LUKS device backing root, refuses to enroll unless a passphrase/recovery keyslot survives, only ever wipes the tpm2 slot, confirms + post-verifies. Both authored + adversarially reviewed to approval. Documented in the handbook (first-boot). - /status freshness dashboard producer —
build-status-json.sh+publish-status-json.sh+status-json.ymlkeep the site's Fedora → Bluefin → Margine version/health page current after every build / smoke / ISO and daily;org.opencontainers.image.base.digestlabel added so the page can flag whether Margine is built on the latest Bluefin. Plusujust margine-status/margine-update+ the/usr/bin/margine-statushelper. - Soft user-smoke gate — a warn-only identity probe in the smoke-boot VM (kernel is CachyOS/BORE, o-tiling enabled, keybindings present, search-light absent, gaming recipe shipped, zz1 gschema applied). Annotates the run; never blocks candidate→:stable promotion.
- AI / local-LLM layer documented + validated — handbook page +
homepage card for
ujust margine-ai(Alpaca);validate-flatpak-refs.ymlchecks every recipe Flatpak app ID against Flathub on PRs + weekly. - GHCR cleanup — daily prune of untagged orphan image versions
(keep-n-untagged), plus host benchmark/diagnostic tools under
tools/bench/(kernel scheduler, gaming FPS, non-HiDPI check).
- Site ISO-date bump now pushes straight to the website's
main(the repo is private/free, so the old PR + auto-merge path silently stranded the bump and the site advertised the previous ISO). - Renovate now tracks the o-tiling release pin (no more silent staleness)
and the config was migrated;
actions/checkoutbumped to v6.
- Fresh ISO installs now submit the Margine MOK import request from Anaconda before the first post-install reboot, mirroring Bluefin's ISO Secure Boot flow so shim can open MOK Manager before the installed system boots.
- Rebase recovery path remains unchanged:
mok-enroll.servicestill runs on first Margine boot when the Anaconda path was not available or the user missed the firmware MOK prompt.
- GNOME extension defaults now live in the system dconf database
(
/etc/dconf/db/distro.d/) instead of a gschema override, so extension settings are applied through the backend GNOME Shell actually reads at first login. - Installer partitioning is declared in the Anaconda kickstart:
zerombr,clearpart, a 4 GiB ESP, a growing btrfs root, and the single-diskignorediskshim for safer fresh installs. - bootc-image-builder in
build-disk.ymlis pinned to an@sha256digest instead of a moving tag. - GNOME branding assets overwrite Fedora's hard-coded logo pixmaps instead of deleting them, so GNOME About renders the Margine logo again.
- sched_ext controls were rewritten as an opt-in Zenity picker:
scx_loaderstays off by default, scheduler changes go throughscxctl/D-Bus/polkit, and tuned profile hooks now gate on active service state instead of enabled state. - README install guidance now recommends rebasing from Bluefin DX while the fresh-install ISO path is being hardened.
- Launcher icons now use a MoreWaita system icon for the scheduler app and a custom Margine documentation icon.
- Documentation launcher now uses
/usr/bin/margine-docs-open: it opens the live docs when/healthzresponds and falls back to/usr/share/margine/offline-docs/index.htmloffline.
- New
ujust margine-airecipe inbuild_files/60-custom.justinstalls Alpaca (com.jeffser.Alpaca) — a Flatpak GUI for local LLMs that bundles its own Ollama backend. No host install, no daemon-running, models downloaded on demand. Recipe also prints distrobox setup pointer for RamaLama CLI power users.ujust margine-ai-removereverses it. - README "What you get" gets a
🤖 Optional AI workflowrow. - Spec yaml (
margine-fedora-atomic/declarations/margine-atomic.yaml) gets a new top-levelai_workflow:section documenting the opt-in model, recommended starter models (llama3.1:8b / qwen2.5-coder:7b / mistral:7b / phi3.5:3.8b), and hardware floor (8 GB VRAM comfort, 16 GB RAM minimum for CPU-only).
- New
ujust margine-gaming-nativerecipe layers Steam + Lutris + RetroArch as native RPMs from RPM Fusion (Heroic / Bottles / Protontricks / ProtonPlus stay Flatpak — no official RPM upstream). For users needing maximum Proton/Wine compatibility — anti-cheat (EAC / BattlEye), VR, Steam Link, NVIDIA proprietary + Mesa-git side-by-side. Cost: +30-60s perbootc upgradeto re-apply the larger layer. - Default Flatpak
ujust margine-gamingstays unchanged for occasional gamers. - README Option C section rewritten to document both paths with the
explicit trade-off. Spec yaml
gaming_runtime.opt_innow hasdefault:andnative:sub-keys. - Inspired by RakuOS's "Native Gaming. Not Flatpak." stance — same trade-off, kept as opt-in second path so the default Margine experience stays upgrade-friendly.
margine-fedora-atomic/docs/adr/0007-sealed-bootable-images-tracker.md: long-form ADR tracking Fedora's sealed bootable container images direction (systemd-boot + UKI + composefs/fs-verity, Secure-Boot- signed end-to-end). Covers 5 action triggers + 9-step migration plan for when production stable arrives (~6-12 months).margine-fedora-atomic/scripts/check-upstreams.shwatchlist getstravier/fedora-atomic-desktops-sealedso the monthly cron flags activity in the test-image repo.- Tracker issue #32 on margine-fedora-atomic with checkbox list of triggers + steps.
ghcr.io/.../margine-gaming:stableOCI image — no longer built or published. The dedicatedbuild-gaming.ymlworkflow, theContainerfile.gaming, thebuild_files/gaming/directory, andinstaller/flatpaks-gamingare all deleted.- Gaming Anaconda ISO —
build-disk.ymlno longer matrixes overmargine+margine-gaming; only the singlemargineISO is built and uploaded to Internet Archive. No moremargine-gaming-anaconda-iso-YYYYMMDDitems. Option C — Switch between Margine and Margine Gaminginstall section in README — replaced withOption C — Add the gaming layer(oneujust margine-gamingstep on top of base Margine).- Rationale: same gaming stack reachable from base Margine via the
already-existing
ujust margine-gamingrecipe (rpm-ostree layer + Flatpaks). Two parallel paths to the same gaming setup was extra surface area to maintain — separate ISO build (60 min CI), separate IA upload (~6 GB / build), separate Containerfile, separate preinstall list, separate ISO download UI on the site. Keeping only the ujust path cuts that whole pipeline. Trade-off: the result is a layered (not ostree-canonical) deployment, which is the same trade-off the recipe already had before this change.
- 11 GNOME core Flatpaks added to the preinstall set (Calculator,
Calendar, clocks, Contacts, Weather, Maps, TextEditor, baobab,
Characters, Logs, font-viewer). Closes the visible gap "the
standard GNOME utility set isn't here" against a vanilla Fedora
Silverblue install — Silverblue ships these as RPM in /usr, Bluefin
DX intentionally strips them, so we restore the set as Flatpaks
(atomic-friendly, ~120 MB cumulative thanks to shared
org.gnome.Platform runtime).
EXPECTED_FLATPAKSin margine-fedora-atomic updated in lockstep.
- 9 Flatpaks added to the preinstall set (Thunderbird ESR,
GNOME Snapshot/Showtime/Papers/Loupe/SoundRecorder, Blanket,
Fragments, Pinta). The previous list was an incomplete starter
set — users on a fresh install were surprised to find no
camera / video player / PDF reader / image viewer / sound
recorder / mail client (the latter despite being declared as
the system mail handler in declarations/margine-atomic.yaml).
The validator's
EXPECTED_FLATPAKSin margine-fedora-atomic is updated in lockstep so the post-boot acceptance test catches any regression on this set.
- Margine Gaming OCI variant — a separate, signed image at
ghcr.io/daniel-g-carrasco/margine-gaming:stable. BuiltFROMthe already-validatedmargine:stableand adds the gaming host stack (gamescope, MangoHud, vkBasalt, GameMode, goverlay, steam-devices, input-remapper, tuned, tuned-ppd, rom-properties-gtk) at image-build time plus a Flatpak preinstall list (Steam, Lutris, Heroic, Bottles, Protontricks, ProtonUp-Qt, RetroArch). End-user switch:sudo bootc switch ghcr.io/daniel-g-carrasco/margine-gaming:stable. Identifies itself asVARIANT_ID=gaming,PRETTY_NAME="Margine Gaming". Files:Containerfile.gaming,build_files/gaming/{install.sh, stamp-os-release.sh,margine-gaming.preinstall}. build-gaming.ymlworkflow —build_push → sign → promote_to_stable → notify. Triggers onworkflow_dispatch,workflow_runafter a successfulSmoke-boot published image(so the variant rebuilds automatically when a new base:stableis promoted), and weekly Sun 05:00 UTC. No MOK secrets needed: the kernel is already signed in the base layer. Promotes:candidate → :stableimmediately after signing (the base was smoke-booted; the variant only adds RPMs + Flatpak declarations, no boot-path changes that warrant a second 25-min QEMU test).build-disk.ymlmatrix on image — produces 4 disk artifacts in parallel (margine + margine-gaming × qcow2 + anaconda-iso) and publishes both ISOs to Internet Archive under per-variant identifiers (margine-anaconda-iso-YYYYMMDD,margine-gaming-anaconda-iso-YYYYMMDD).- RPMFusion enabled in the gaming variant — the base image strips
RPMFusion after using it transiently for the CachyOS kernel install;
the gaming variant re-enables free + nonfree and keeps them, since
the entire gaming RPM stack lives there and users will need the
same repo set for
dnf upgrade/rpm-ostree upgrade. - Trade-off note in
ujust margine-gaming— the existingujustrecipe (rpm-ostree overlay) now prints, before its confirmation prompt, what the layering choice implies (LayeredPackagesbranch, slower upgrades, occasional file-conflict rebases) and points users to the variant image as the ostree-canonical alternative.
- Candidate → stable promotion model:
build.ymlnow publishes only:candidate+:candidate.YYYYMMDD;smoke-boot.ymlboots that candidate in QEMU and only on successskopeo copy --preserve-digeststo:stable+:stable.YYYYMMDD+:YYYYMMDD. Eliminates the class of "build green, boot red" leaks. - Layer A
systemd-analyze verify default.target: ordering-cycle detection at build time, catches regressions like the one that put a deployment into emergency.target on 2026-06-01. - Pre-build GHCR login: authenticated base-image pull (5000 req/h instead of 100/h anonymous), fixes intermittent 403 on bluefin-dx:stable after cache reset.
- OCI archive intermediate for the move-to-root-storage step
(replaces the
podman save | sudo podman loadpipe which corrupted blobs under memory pressure on the degraded-ZFS host). build-disk.yml: ISO + qcow2 builder, publishes via Internet Archive (torrent + 3 HTTP mirrors, seeded forever) + HTML index onfiles.the-empty.place. No origin upload bandwidth for binaries.- ntfy push notifications: build/smoke-boot/disk-build outcomes
- click-to-open-run URL. Topic via
NTFY_TOPIC_URLsecret.
- click-to-open-run URL. Topic via
margine-staleness.timer+margine-upgrade-notify.service: client-side awareness of stale upstream and post-upgrade events, installed via/etc/skeluser-systemd.margine-configure-zen-browser: per-profileuser.jssetting DuckDuckGo as default search engine.- GNOME extensions added: o-tiling (binary-tree auto-split, replaces Tiling Shell as default tiling), Hide Cursor, Caffeine.
build_files/build.shnow stamps/usr/lib/os-releasewith Margine identity (NAME=Margine,ID=margine,VARIANT_ID=margine,ID_LIKE="fedora bluefin"). This makescat /etc/os-release,hostnamectl, and GNOME About all report "Margine", and letsmargine-validate-atomic-layoutsucceed on the actual deployment.
- System-wide Flatpak preinstall moved from
/etc/ublue-os/system-flatpaks.list(legacy uBlue path, no longer honored by Bluefin) to/usr/share/flatpak/preinstall.d/margine-defaults.preinstall(systemd's standard preinstall API). configure-gnome-extensionsis now replace-style rather than additive: builds the full enabled-extensions list from the declaration and writes it directly viagsettings set, dropping anything no longer declared (e.g.tilingshellafter the switch too-tiling). Uses an on-disk presence check rather thangnome-extensions list(which only reflects the running shell).margine-seed-etc-passwd.serviceordering:After=local-fs-pre. target(waslocal-fs.target→ ordering cycle → emergency.target).- Plymouth + boot fallback colors: pure black
#000000background everywhere (was warm brown). - GDM logo: empty string (was a 2400x700 banner image that got upscaled fullscreen by GNOME 50 greeter).
- App folders: 6 folders (Office / Graphics / Photography / Audio /
Video / System). The folder set started as Italian-labeled
(Grafica/Foto/Sistema) and was renamed to English on 2026-06-01
so existing in-the-wild deployments may briefly show either set
until
configure-gnome-app-foldersruns again.
- Dropped the
kittyFlatpak preinstall (build.sh) and the kitty default-terminal gschema override. Bluefin's Ptyxis stays as default. - gschema
favorite-appsupdated toorg.gnome.Ptyxis.desktop.
custom-kernel/install.shinstallssbsigntoolsup-front sosbsignis available when signing vmlinuz (fixed exit 127).- v4l2loopback is built best-effort; failures do not block the image (Universal Blue cache-mount limitation, documented inline).
mok-enroll.serviceis written + enabled; runs once at first boot, marks completion with/var/.mok-enrolled. Recovery procedure for a missed MOK Manager confirmation is documented inmargine-fedora-atomic/docs/07-secure-boot-tpm2.md.
First successful build pushed to ghcr.io/daniel-g-carrasco/margine:stable
(commit 74449fc, build 2026-05-26): Bluefin DX + MOK-signed CachyOS
kernel + Margine Flatpak preinstalls + Margine GNOME defaults.