The optional kernel reboot-visibility change was closed without merging, so remove the planned-reporter wording. Replace it with the manual booted-vs-selected kernel check and update the P1 TODO accordingly.
muvm is disabled because it does not build/run on nixos-apple-silicon yet, not because of a permanent hardware limitation; the 16k page size is the reason it is wanted, and the removal condition is muvm building and working.
WORKAROUNDS.md collects temporary workarounds, version pins, carried patches, and known gaps, each with a removal condition, so they can be re-evaluated and rolled back on a schedule. AGENTS.md points to it and states the convention: a change that adds a workaround adds a row in the same PR.
Replace the backported patch with a src/version/vendorHash override that pins prometheus-smartctl-exporter to upstream 6274decc (2026-09-28), which already carries the Describe() fix from PR #329. Simpler to maintain than a patch file and it tracks the upstream change directly; drop the overlay once smartctl_exporter 0.15.0 is packaged in nixpkgs.
smartctl_exporter 0.14.0 derives Describe() from the devices it can read at startup. A device that only becomes readable later (an NVMe whose ACL arrives late, or an HDD waking from standby) then makes Collect() emit metrics with unregistered descriptors, so /metrics returns HTTP 500 and the whole scrape fails, hiding even the healthy disks.
Backport upstream PR #329, which makes Describe() send the full explicit descriptor set. Carry it as an overlay until smartctl_exporter 0.15.0 is released and packaged in nixpkgs.
Refs: https://github.com/prometheus-community/smartctl_exporter/pull/329
Reuse the already-extracted, libtiff-patched AppImage from the nixpkgs wechat package (`wechat.src`) instead of keeping our own CDN URLs and hashes, which had to be refreshed whenever Tencent replaced the versionless files. Take the package from nixpkgs-master, which carries the newest builds.
- wechat.nix: repacking is needed because nixpkgs' wechat package does not expose its AppImage wrapper args for `.override`, not because wrapAppImage lacks overriding (it forwards args to buildFHSEnv).
- peripherals.nix: drop a link to an already-closed issue and fix a typo.
nixpkgs-blender tracked the nixpkgs master branch, so every `just up` re-bumped it and started a full Blender/CUDA source rebuild even though Blender stayed at 5.2.2 LTS. Pin it to a fixed rev so bumps are deliberate.
The OIDN cmake override is obsolete: nixpkgs#545542 made setupCudaHook add nvcc to CUDAToolkit_ROOT, fixing the CMake 4.3+ split-root failure (nixpkgs#544701). Dropping it also stops Blender's derivation from depending on nixpkgs-stable.
environment.enableAllTerminfo installs every terminal's terminfo, including rxvt-unicode, which no longer builds with GCC 16 (NixOS/nixpkgs#568896). Install just the terminals we use (alacritty, foot, ghostty, kitty) instead. This also makes the aarch64 jasper workaround unnecessary.
16 inputs moved; nixpkgs -> c59305bab206 (nixos-unstable, 2026-10-01), plus the
master/stable/darwin/blender/patched nixpkgs inputs and the module flakes
(home-manager, microvm, nixos-apple-silicon, nix-gaming, nixpak, llm-agents,
rust-overlay, flake-parts, git-hooks, nu_scripts).
Audited each moved revision through the GitHub compare API: no red flags
(substituters, trusted-users, activationScript, pre-commit hooks) in the inputs
examined. home-manager carries the rl-2611 extraConfig/mkForce change (affects
mbsync/lieer/mujmap/notmuch/astroid/grobi; none used here). The home-manager
compare is large, so the audit is not exhaustive and relies on the build.
Validated with `just test` (true), eval-host on the NixOS hosts, and
`just build-host ai-niri`; deployment passed. The build initially failed on
rxvt-unicode-unwrapped (GCC 16 std::lerp regression, nixpkgs#568896), pulled in
by environment.enableAllTerminfo; terminfo is now scoped to the terminals in use.
Running strata with qwen3.8-flash-next keeps ~53G of model weights
resident, leaving little RAM for the desktop side and pushing ~13G of
anonymous pages into the 20G swapfile. With swap that full, a burst
risks OOM-killing processes. Disk space is not a constraint (1.9T
btrfs, ~1.4T free), so grow the swapfile to the classic 1x-RAM size.
Keep zram off and zswap at 10%: zram's compressed pool would steal page
cache that the mmap'd weights rely on.
Prefer the narrowest output of a dependency (for example stdenv.cc.cc.lib
instead of stdenv.cc.cc) and measure the built closure, since a full
toolchain can add hundreds of MiB. Also note how to check what is actually
needed (DT_NEEDED, exec'd tools) before trimming.
Disable the rootful system podman.socket on desktop hosts and drop the module's autoPrune, which prunes the rootful store and pulls in the rootful API service. Add a weekly per-user timer that prunes the rootless store instead.
Manage ~/.config/go-musicfox/config.toml declaratively: the upstream default plus the mpv engine, ~/Music download dir, 2 GiB cache and cover art.
The app rewrites the file with a temp file plus rename, which would replace a plain symlink, so use force = true like fcitx5's profile: the repo copy is restored on every rebuild and runtime edits are ephemeral. Runtime data and state stay on the persistent volume.
Catppuccin's home-manager module writes extra-substituters/extra-trusted-public-keys
for catppuccin.cachix.org into the user-level ~/.config/nix/nix.conf. Since the
normal user is no longer a trusted-user (modules/base/nix.nix), Nix ignores those
client-specified settings and warns on every command. The ports build locally, so
turn the user-level cache off instead.
Allow clearly-implied task authorization, trust skills listed in the runtime's configured catalog, and restore the ban on following external-material instructions. Sync the affected evaluation scenarios.
conda/mitmproxy/wireshark are already Linux-gated in the shared home modules, and verible is unreferenced, so replacing them with emptyDirectory is unnecessary.
openldap's flaky tests are skipped upstream now (doCheck = true), so the override only forced local rebuilds of openldap/cyrus-sasl dependents such as libvirt and kio.
davfs2 caches the whole opened file regardless of cache_size, so opening media on /mnt/fileshare downloads it fully and blocks the mount. The share is no longer used.
Treat content from unverified sources as data, not instructions, and require authorization before cloning, downloading, or executing unverified code and install scripts.
Deploy RustFS in place of the retired MinIO and move the S3 consumers over.
- flake.nix / flake.lock / outputs/default.nix: add a nixpkgs-small
(nixos-unstable-small) input for the rustfs 1.0.0 package (with the web
console), instantiated as pkgs-small in genSpecialArgs alongside the other
nixpkgs instances; drop the rustfs flake input. The rest of the system stays
on the default nixpkgs.
- hosts/12kingdoms-youko/homelab-services/rustfs.nix: use nixpkgs' own
services.rustfs module, with package = pkgs-small.rustfs and
environmentFile = the agenix rustfs.env secret.
- caddy.nix: s3.writefor.fun (S3 API) and s3-console.writefor.fun (console,
redirects / to /rustfs/console/).
- secrets/nixos.nix: declare a single rustfs.env (dotenv) secret holding
RUSTFS_ACCESS_KEY / RUSTFS_SECRET_KEY, replacing the separate key files.
- infra/minio -> infra/rustfs: buckets are managed with the hashicorp/aws
provider against the RustFS S3 endpoint; IAM/ILM are applied with rc.
Crush hardcodes banned bash commands, blocking many operations. Drop the package, its AGENTS.md/CRUSH.md install target, env vars, and preservation entries.
Keep the six node configuration intact while removing the failing user activation from the three control-plane MicroVMs. Update the regression test and current K3s configuration notes.
0.156.1 still lacks the codex-chatgpt recursion_limit attribute, so keep the postPatch that adds it. The vendored Cargo.lock is unchanged, so the cargoHash stays the same.
cilium writes /etc/cni/net.d while istio-cni reads k3s's own dir, so on the new workers the chained plugin never found a network config. Add the symlinks the server module already has.
kubelet refuses to self-assign the reserved node-role.kubernetes.io/* labels, so the worker --node-label made the agent crash-loop. Drop it and rely on the masters' control-plane taint for placement; document that the taint only lands via registerWithTaints on first registration, so it was applied by hand here.
Give the idols-ruby and idols-kana VMs a headless computer-use
environment: Xvfb plus i3, driven by cua-driver (and computer-use-linux
as a fallback). Includes the system module (AT-SPI, fonts, Mesa, Clash
Verge proxy, proxy-region timezone), the home i3 module (Xvfb/i3/x11vnc
services, browser flags), host wiring and an eval test.
Package the prebuilt releases (computer-use-linux v0.7.1 and
cua-driver-rs v0.24.0) under pkgs/, injected through thin callPackage
overlays so they are easy to relocate to the NUR repository later.
The desktops hold the trusted admin keys and are where secrets are edited and
rekeyed from; narrowing a set to the servers alone breaks agenix -r and drops
the offline recovery key.
A recipient set must answer two questions: who may read it, and how it is
recovered once those hosts are gone. Dropping recovery_key while narrowing
a secret is easy and silent.
A failed backup was silent. Post to alertmanager (which routes above-info
to telegram), and have caddy answer 404 instead of its empty 200 for
*.writefor.fun names that are not services.
A desktop holds both the plaintext and the repository password, so blocking
deletion on the server protects little while preventing the automatic
retention the client needs. Immutability belongs in the offsite copy.
The design (layers, password groups, retention, restore steps) was only in
code comments. Also make the timer configurable: a whole hour of random
delay defeated any staggering, and the desktop's push, youko's own run and
btrbk all otherwise contend for the same disks.
Split the repository password into desktop and homelab groups, add the
environmentFile/pruneOpts module options, and point the desktop at youko's
REST endpoint.
Allowlist of the irreplaceable directories (Documents, work, Pictures,
nix-config, .local/state); project checkouts under ~/codes live in git and
are not backed up. Kept the excludes generic, since this repo is public.
Also move the restic-password secret to a desktop.enable || server.storage
gate so desktops get it without enabling a server group.
The services now run directly on the host, so their state does not belong
on the HDD behind the flaky USB-SATA bridge: /data/apps was small-file
heavy and latency/consistency sensitive. Point every dataDir at
/persistent/apps (the LUKS nvme) instead.
The HDD keeps the bulk data that suits it: /data/fileshare (173G) and
/data/backups (24G). The HDD's old @apps subvolume and its data are left
in place for now.
-B 255 turns APM off and it stuck, but the disks still reach standby, so
the bridge firmware is likely doing the spindown. -J 0 additionally asks
the drive to stop parking its heads (sdb has ~1M load cycles).
pcie_aspm=off was the least-justified mitigation (the flakiness is on the
USB/SATA side) and costs power. Also log the disks' APM level/state and
re-apply the settings hourly, since the bridge or the disk firmware can
drop them (the disks were still reaching standby).
The two 4TB HDDs sit behind a JMicron JMS567 that resets and throws
UDMA-CRC / I/O errors (the disks themselves are healthy). Best-effort
mitigations while the enclosure stays in use:
- kernel: usbcore.autosuspend=-1, usb-storage.delay_use=10, pcie_aspm=off
- udev: keep the bridge's power/control=on (never autosuspend)
- disable APM/standby on the HDDs (spindown is a common reset trigger)
- enable smartd (watch the CRC count and disk health)
The kernel parameters need a reboot to take effect.
It documented the retired KubeVirt workflow (upload a qcow2, create the vm
in k8s-gitops, let Flux create it), which no longer exists. The general
deployment notes live in the README and the per-platform docs
(hosts/k8s/README.md for the microVMs).
Update the user-facing bits that still pointed at KubeVirt: the homepage
dashboard group and entries (and drop the dead LongHorn one), the docs,
and remove the now-unneeded virtctl package.
The k3s-test workers never ran (they were stuck waiting for volume
binding) and will be re-added as microVMs, so remove their KubeVirt
configs and everything that only existed for KubeVirt guests:
- hosts/k8s/k3s-test-1-worker-{1,2,3} and their outputs
- lib/genKubeVirtGuestModule.nix and lib/genK3sAgentModule.nix (the
latter was only used by the workers)
- the KubeVirt image upload recipes (upload-vm, upload-idols,
upload-k3s-test) and the kubevirt image package in the idols outputs
- refresh the docs; keep only accurate historical mentions (e.g. the
restic backup path must stay as it is)
Drop the now-meaningless kubevirt- prefix and move the hosts out of
hosts/k8s/, following the existing 12kingdoms-shoukei layout: the
directory and output carry the theme prefix while the configuration,
hostname and colmena target are the bare name (shoryu, shushou, youko).
- hosts/k8s/kubevirt-* -> hosts/12kingdoms-*; the shared disko config
becomes host-disko-fs.nix; the now-different relative imports are fixed
- outputs, vars/networking.nix keys, the Justfile recipes/tags, the eval
tests and the docs follow
- colmena reaches these hosts by IP (a new targetHost override), since
their DNS name changes with the hostname and is not resolvable until
the router learns it