Open items¶
What is still open. A finished item migrates to history/: this file only grows with new work, and shrinks when work ends.
Convention inherited from the single-file era: every item explains the WHAT, the WHY and the known trap. The paragraph is worth more than the title.
AUDITED on 16/08/2026 against the actual tree, because this file had drifted the way rule 16 describes: six items were already DONE and still sitting here, and one was carrying 70 lines of finished work. What was closed is in the august history.
-
[~] The shared memory exists; what is open is the KNOWLEDGE in it (opened 24/08/2026). The server, the package and the three clients landed the same day (see the august history and notes/apps/basic-memory.md). None of what is below is declarable, which is exactly why it is here. • THE DIRECTORY IS A GIT REPO as of 24/08/2026, with the layout, the frontmatter contract and one worked example committed, pushed to
v1cferr/context, PRIVATE. Private is not a detail here: it is the only repo of mine that holds personal context rather than configuration, so it is the one place where "public by default" would be wrong. • ARCHIVE AND KNOWLEDGE ARE NOT THE SAME THING, and dumping years of chats into one pile would produce a memory that confidently quotes a preference I dropped in 2024. What goes in isarchive/(evidence, immutable, per provider and year) andknowledge/(what is true TODAY, curated, with the archive as its source). The extraction between the two is work, not an import. • PROVENANCE IS THE PART THAT MAKES IT TRUSTWORTHY: who said it (me, or a model inferring), when, from which conversation, and whether it still holds. basic-memory hasbm schema(validate, infer, diff), so the frontmatter contract can be CHECKED instead of hoped for. • THE IMPORTS ARE READY ON TWO OF THREE:bm import chatgptandbm import claude conversations|projectsexist in the source. Gemini has no importer, so a Google Takeout needs a converter of mine, and the honest shape is Markdown inarchive/gemini/<year>/with the same frontmatter as the other two, so the next index reads it without knowing which provider it came from. • THE ORDER I CHOSE: Gemini and ChatGPT first, Claude later. The Claude export is not blocked, since I am the Primary Owner of the FAI organization and that is who Anthropic lets request it; it is just not the first pile worth curating. -
[ ] The one follow-up the gate's hardening left open (23/08/2026). The dependabot half was CLOSED the same day (see the august history); this is what stayed. • THE COMMIT MESSAGE IS ONLY CHECKED HERE.
convcoandprose-stylerun at the commit-msg stage, whichnix flake checkcannot reach: there is no message inside that sandbox. So a commit written on another machine, or with--no-verify, is unchecked. The fix is a CI step running both over the PUSHED RANGE, and it is only worth doing the day a second machine starts writing to this repo. -
[ ] The page count in
docs/notes/README.mdhas drifted (measured 23/08/2026). The Conventions section says "16 of the 51 pages cross thesystem/andhome/boundary", and there are 58 pages today. The number is not decoration, it is the measurement that REJECTED mirroring the tree, so fixing it means recounting both halves (how many pages cross, how many reference two or more modules) and not just editing the total. Left as an item instead of a blind edit, because a re-measured number is worth something and a guessed one is worse than the stale one. -
[~] The T480 before it leaves the house (opened 22/08/2026). It is my mother's machine, it goes to another city, and after that every mistake here costs a phone call instead of a minute. The Windows side lives in that machine's OWN repo; what is listed here is either this repo's or a joint decision. • CLOSED THE SAME DAY, so nobody reads this item as untouched: the MASQUERADE toward 10.10.10.6, the panel user, the Moonlight pairing, the DoH policy on her browsers and the watchdog's numbers. The reasoning for each is in the august history; what is left below is what genuinely cannot be closed from this side of the house. • THE ONLY VALID TEST IS FROM ANOTHER NETWORK, and none of today's proves anything about her house. With the machine on the home Wi-Fi the tunnel closes by hairpin on the router itself, and
wg showeven displays192.168.1.1as the endpoint while the file saysvpn.v1cferr.dev. The protocol: phone hotspot, tunnel coming up on its own,ssh t480answering, and a Moonlight session lasting past 2 min (a drop at ~4 s is the MTU signature). Do it while the machine is still within arm's reach. • THE GHOST REAPER DOES NOT EXIST OVER THERE, and it bit once already on 22/08: a client that vanishes with no teardown leaves Sunshine answeringSUNSHINE_SERVER_BUSYforever, and Moonlight then refuses to open a new session, so from the client the host is simply broken. The remedy is arestartand the pairing survives it, which is what makes a watchdog cheap to write. A flaky public Wi-Fi is a ghost factory, so this is not an edge case at her place. • THE WINDOWS VARIANT NEEDS A DIFFERENT SIGNAL. Here the reaper readsBUSYplus no bound UDP socket; over there the three sockets WERE bound with the client long gone, so that test would never fire. What did not lie is the traffic:wg show <tunnel> transferbarely moved. Condition: BUSY plus a byte delta under a floor, HELD for a few cycles so a session being born is not killed. • IT DROPPED IN PRIORITY THE MOMENT RDP LANDED, and that is worth writing down instead of just doing the work: a ghost used to mean the machine was unreachable, and now it means one service needs restarting through a path that does not depend on it. Convenience, not a lifeline. • NO REAL SESSION HAS RUN YET. Paired is not streaming:moonlight list 10.10.10.6answersDesktop, which proves the pairing and nothing about video. Until a session runs, the encoder, the packet size and the bitrate are all still theory. •max_bitrateIS A PLACEHOLDER at 10000. The bottleneck out of there is HER upload, which nobody has measured. Raise it after a real session, not before. • THE MACHINE'S REPO HAS NO REMOTE. It is a local git on a laptop that is leaving, so the inventory, the scripts and the reasoning die with the disk. It is not this repo's content and does not belong in it (rule 14, and it holds her machine's specifics), so the answer is a PRIVATE repository of its own, pushed before the trip. • THE LID QUESTION IS ANSWERED AND THE ANSWER COSTS NOTHING: a closed lid stops Sunshine's capture, because there is no panel to duplicate, so RDP is the headless path and both are declared. What remains is the DISPLAY TIMEOUT, 15 min on AC, which is the same class of failure and has not been tested: if a stream comes back black with the lid OPEN, that is the first suspect. • STILL OPEN OVER THERE, decided by whoever owns that machine:PasswordAuthenticationis stillyeson an sshd that only listens inside the tunnel, and BitLocker isFullyDecryptedon a laptop that will live in someone else's house. -
[ ] Quality probe for the UFSCar VPN: no measured target (opened on 14/08/2026). The pill's hover popover measures latency/jitter/loss by pinging a host INSIDE the tunnel. For FAI the target is pinned and measured (
200.136.209.236, see today's history); for UFSCar there is none, because I never brought that tunnel up with the panel ready to find out who answers in there. Meanwhilevpn stats-jsonfalls back (the gateways from the tun routes) and, if nobody answers, the panel says "no probe". • DO NOT GUESS A UFSCar IP to "solve" it: a target that is not routed through the tunnel would measure the home internet. The-I <iface>protects against that (it turns into silence instead of a wrong number), but the silence is the symptom of guessing. • HOW TO CLOSE IT: connect (vpn connect ufscar), look atip -4 route show dev tun0, ping candidates withping -I tun0 <ip>and pin whichever answers inprobe_candidates(), insystem/net/vpn.nix, together with the measurement, the way the FAI one is. -
[ ] WireGuard peer
fai-workstation(10.10.10.5): alive or legacy? (opened on 10/08/2026) Measured with the newwg-status: in 17 days of router uptime it did not do ONE handshake. And it is not a forgotten passive peer: it haspersistent_keepalive = 25, which exists precisely to keep the connection up. • The two possible readings, and they call for opposite actions: either the workstation has WireGuard stopped (and someone counts on that tunnel without knowing it never comes up), or the peer is residue and should leave the router by the zero-legacy rule. • DO NOT DELETE BEFORE CHECKING: the~/FAI-workstationmount (rclone SFTP) comes up with the FAI VPN, not with this tunnel, so the peer LOOKS orphaned without being it. Check from over there withwgbefore deciding. • Thenotebookpeer (.2) WAS REMOVED on 19/08/2026, for the reason this item is still open about: nobody could say which machine held its private key, and thewgzone reaches the whole LAN. That one had never handshaked at all, which made the call easy. THIS one has apersistent_keepalive, so somebody expected it to be up, and that is the difference. • MEASURED AGAIN on 13/09/2026, in the hardening audit: still no handshake, now across 14 days of a DIFFERENT uptime. Two independent measurements a month apart agreeing is as close to an answer as this item is going to get without asking the workstation, so the reading has shifted from "unknown" to "residue", and what is missing is thewgfrom over there to make it final. -
[ ] WireGuard peers have no
preshared_key(opened on 13/09/2026, from the hardening audit). All five peers authenticate with the key pair alone. The PSK is the standard second layer: it defends against harvest-now-decrypt-later, and it is what keeps a LEAKED private key from being enough on its own. • WHY IT WAS NOT DONE WITH THE REST: it is not a router-side change. A peer whose PSK is set on one end and not the other stops handshaking, so every client config has to be updated inside the same window, and two of those clients live in other people's houses (the mother's T480, my brother's PC). That is a scheduled operation, not auci set. • ORDER THAT DOES NOT LOCK ANYBODY OUT: one peer at a time, starting with the phone, which is the one I hold and the one that is now the only admin source for the router (guides/router-hardening.md). -
[ ] The router keeps no log that survives a reboot (opened on 13/09/2026, from the same audit).
system.@system[0].log_size='128'KB in RAM and nolog_ip, so the evidence of a compromise dies with the next power cut. Everything the audit fixed is PREVENTION; there is currently no DETECTION at all on this device. • THE FIX IS NOT Auci set: it islog_ip='192.168.1.10'plus a syslog receiver on the desktop, which is a NixOS module and belongs insystem/net/. The router half is one line and the useful half is the other one. • THE TRAP TO SIZE FIRST: the desktop is also the DNAT target for 80/443/2222, so a log pipe from the router into it is a service listening on the LAN, and it has to refuse everything that is not 192.168.1.1. A log receiver open to the house is a way to forge the record you installed it to trust. • AND IT IS WORSE THAN "NOT DURABLE":logreadasv1cferrdoes not fail, it HANGS. Measured 13/09/2026 while looking for auth failures: the command returned empty on this side because the ssh call timed out, and TWO invocations were still sitting on the router afterwards, blocked on the log socket. So the log is not merely lost at the next reboot, it is unreadable withoutsudoand it swallows whoever tries. Any collector written for this has to run as root on the router side, and anything that shells out tologreadunprivileged needs a timeout or it leaks processes. -
[~] ACTUALLY TEST Wake-on-LAN (opened on 10/08/2026). The config is applied and the
40-enp7s0.linkis generated withWakeOnLan=magic, but NONE of that proves the machine wakes up. Only powering it off and sending the packet proves it. • DO NOT CLOSE THIS ITEM WITHOUT THE TEST. It is the same mistake as today's HEVC, in reverse: there I closed by report without measuring; here the temptation is to close by applied config without triggering it. Correct config and real effect are different things, which is exactly what fw4 taught today by ACCEPTING asrc_ipas a list and DISCARDING the section. • SCRIPT:sudo poweroff, then from the phone over WireGuard,ssh v1cferr@192.168.1.1 'sudo wake-desktop', and the machine has to come on. • CURRENT STATE, measured:power/wakeup = disabledandWake-on: d. The.linkis only applied by udev when the interface APPEARS, that is, from the next boot on. To arm it before that, without dropping the link:ethtool -s enp7s0 wol g. • IF IT DOES NOT WAKE, the next suspect is the BIOS: "Wake on LAN / Wake on PCIe" has to be on there too. The OS arms the NIC; the motherboard decides whether it accepts the signal. • THIS WILL NEVER COVER A POWER OUTAGE, and that is not a WoL failure: a real cut takes away the +5VSB and the NIC loses the armed register. For "the power went out" the answer is Restore on AC Power Loss in the BIOS, and then WoL becomes irrelevant, because the machine turns itself on. -
[ ] Tray: the TOOLTIP, which does not exist anywhere on the bar (opened 30/07, narrowed 16/08/2026). Everything else in this item was DONE and its reasoning now lives in notes/desktop/bar.md and notes/desktop/quickshell.md: the click, the hover fix (PopupWindow to a layer surface, Hyprland#6682), the visible-hover contrast tokens, the XEmbed bridge and the ghost-icon diagnosis. The item had been carrying 70 lines of finished work, which is the drift rule 16 describes. • Quickshell's SNI exposes
tooltipTitle/tooltipDescriptionready to use; the pattern to follow is the popovers (an anchored PanelWindow, see UsagePopover.qml). • MEASURED on the live items, and it is why a single field will not do: Discord publishes a ToolTip with the title "Discord", Sunshine leaves it EMPTY and only has Title="sunshine", and the icon from the XEmbed bridge has NEITHER. So the cascade is tooltipTitle to title to id, and for the bridged ones it has to resolve the X11 WM_CLASS. • MEASUREMENT NOTE: counting tray items withbusctl --user list | grep StatusNotifierItemgives 0, which is FALSE, because an app registered under a unique name (:1.82) does not match. The authoritative source is the watcher'sRegisteredStatusNotifierItems. -
[ ] SSOT still pending: the HOME
/home/v1cferrtomy.user.home. RECOUNTED on 16/08/2026 and the item was understating it: 8 files, not the 5 written here before (dolphin.nix, Theme.qml, restic.nix, fai-workstation-mount.nix, home/default.nix, plus core.nix, drive-mount.nix and grad-radar.nix). LOW priority on purpose: unlike font/color/connector, the path does not change when the hardware changes. That is also why the count drifted unnoticed, and whydead-configcannot catch this one: a literal is not a dead declaration, it is a missing one. -
[ ] IMPERMANENCE on the Kingston: my idea (30/07), inspired by https://github.com/Misterio77/Foundry. An ephemeral root (tmpfs or a subvolume wiped at boot) plus an EXPLICIT list of what persists. It fits two things this repo already has: rule 6 (Nix = app+config; state = restic) would stop being a convention and become ENFORCED by the system, since whatever is not declared as persistent simply does not survive the boot; and it absorbs what used to be a separate one-line item ("check whether encrypted declarative state is possible"), because the natural pair is impermanence + LUKS, and LUKS is already decided against below. POINTS TO DECIDE FIRST, measured today: the 567 GiB of non-Nix (Bottles 319, Jellyfin 132, Games 47) are LARGE and legitimate state. Impermanence does not erase them, but it forces declaring every path, and getting the list wrong means losing a save or a prefix on reboot. Candidates: the
impermanencemodule (nix-community) or the Foundry scheme. THE MIGRATION ALREADY HAPPENED (01/08/2026) without turning impermanence on, so the original premise ("do it together, on a fresh install") has expired: now it is converting a machine in use, which was precisely the path I wanted to avoid. The btrfs layout saves most of the cost: what is missing is@-blankand the list, not a reinstall. DECIDED on 01/08/2026, while putting hosts/nixos-kingston together (the LAYOUT is already done): • btrfs YES, not out of taste, but because /nix and /persist need to be separate volumes FROM the install onward; flat ext4 would cost a second reinstall. Subvolumes created:@ @home @nix @persist @log @swap. It matches Foundry (root = a subvolume wiped at boot, not tmpfs; tmpfs would cap the root at the 15 GB of RAM). • LUKS NO: a passphrase at boot would kill the autologin that Sunshine depends on for remote access after a power outage. It is the deliberate difference from Foundry. •@homeas a PERMANENT subvolume (Foundry does not have one), an intermediate stage on purpose: turn impermanence on at the root first, and only then decide whether to extend it to home. It locks nothing in: extending it is wiping @home through the same mechanism, with no reinstall. It is the answer to the 567 GiB risk above, since declaring everything on the first try is where you lose. •/var/libis NOT a subvolume, and that is deliberate: if it were permanent, nothing would force declaring anything. A consequence to remember: the service state the cutover copies in there (uid-map, NetworkManager, bluetooth...) is WIPED on reboot once the feature lands, so it has to move to /persist and be declared. That is the work, not a bug./var/lib/sbctlIS FIRST ON THE LIST and the only one that makes the machine NOT BOOT if it is forgotten: those are the Secure Boot keys (see system/core/secureboot.nix). Without them the next switch does not sign GRUB, and with Secure Boot on the firmware refuses the bootloader. Recovery = turn SB off in the BIOS +sbctl create-keys+enroll-keys -magain, with the BIOS in Setup Mode. Declare it BEFORE turning the ephemeral root on. MISSING only: the@-blanksnapshot (the base of the rollback) and the persistence list. The blank is NOT now-or-never, since an empty subvolume created later is identical to a blank snapshot. ── HAVING READ THE FOUNDRY CODE (02/08/2026), what changes in the plan ────────────── PREMISE CORRECTION: btrfs is NOT mandatory for impermanence. The most common path in the community is a tmpfs root, and with a bind mount it even runs on ext4. The choice is still RIGHT, but for the right reason: btrfs gives an ephemeral root without spending RAM, and RAM is exactly what is short here (15 GB). Do not repeat "it is mandatory". It is only two files in Foundry, and the paths below are THEIRS, not paths in this repo:Foundry:hosts/common/optional/ephemeral-btrfs.nix(the wipe) andFoundry:hosts/common/global/optin-persistence.nix(the list). The rest of the persistence is DISTRIBUTED: each service module declares what it needs to keep (openssh.nix, podman.nix, jellyfin.nix...). That is the pattern to copy, and it matches system/services/*.nix./srvIS THE BIGGEST RISK, and it was not written down: it is NOT a subvolume, it lives in@, and it is where the Jellyfin library lives (132 GiB). Foundry persists/srvexplicitly. Turning the ephemeral root on without that ERASES the library on the first boot. Before sbctl on the list. Foundry's minimum list, all of it applicable here:/etc/machine-id(a file, not a dir),/var/lib/systemd,/var/lib/nixos,/srv. The/var/lib/nixosone is the UID/GID MAP, and losing it means uid reassignment, which is the SAME class of bug that broke Docker/Postgres/Sunshine on the cutover (see the cutover damage)./var/logdoes NOT go in: Foundry lists it because it has no subvolume for it; here@logalready handles it, and declaring both would put a bind mount on top of the subvolume.neededForBoot = trueon/persist(Foundry sets it; today it is false in disko).dont-wipe: a marker file at the top of the filesystem that makes the script SKIP the wipe. COPY IT, it is the difference between "boot loop" and "I touch a file from the live USB". SYSTEMD INITRD FIRST, in a separate commit: Foundry runsboot.initrd.systemd.enableand the script has two paths, thepostDeviceCommandsone being the legacy path. Turn the systemd initrd on by itself, reboot and confirm, and only then add the wipe. Two boot risks in a single commit is how you end up not knowing which of the two broke. Adapt the names in the wipeScript: Foundry usesroot/root-blank/persist; here it is@/@-blank/@persist. Getting that wrong does not produce an evaluation error, it produces a broken boot. Copy the impermanence#254 workaround too (/var/lib/privateat 0700 +RemainAfterExit = falseon systemd-tmpfiles-resetup), otherwise a service with DynamicUser breaks. And@snapshots(btrbk) survives by design: it is top-level, it does not live inside@. ── HOW TO DE-RISK THE SWITCH (23/08/2026), because the fear here is the correct one ── The premise of this item is a persistence list that has to be right on the FIRST boot, and it does not have to be: the ORDER is what makes a wrong list cheap. • IN A VM FIRST, and there is a tool for exactly this:nix build .#nixosConfigurations.nixos-kingston.config.system.build.vmWithDiskoformats VIRTUAL disks with THIS repo's disko layout, so the same@ @home @nix @persistexist and a wrong list costs an image instead of the 132 GiB Jellyfin library.nixos-rebuild build-vmis the WRONG tool here: with a disko layout it hangs waiting for the root partition (disko issue #668). • BTRFS GIVES A ROLLBACK THAT TMPFS CANNOT, and that is what dissolves the fear: the wipe issnapshot @ -> @-old-NBEFORE restoring@-blank, keeping the last N roots. A path forgotten on the list stops being a loss and becomes "mount the previous snapshot and copy what was missing". Retaining N is the most important line of the wipeScript, more than the wipe itself. • ONE BOOT RISK PER COMMIT, which extends what is already written above: (1) the script plusdont-wipe, inert; (2) systemd initrd alone, reboot, confirm; (3)/persistwithneededForBootand the declared list, reboot WITHOUT the wipe, which proves the binds work while the system is still persistent; (4) only then the wipe. • PROVE THE RESTIC RESTORE BEFORE ANY OF IT. Rule 6 says state lives in restic and impermanence is that rule becoming law. Turning the law on without ever having restored something from that backup is the one version of this that costs real money. • MEASURED 23/08/2026 IN THE DISKO VM, and it confirms the /srv worry with evidence: systemd createssrv,var/tmp,var/lib/machinesandvar/lib/portablesas SUBVOLUMES INSIDE@, so a wipe of@takes them along.btrfs subvolume list /on a fresh install shows them at "top level 256", which is@itself./persistalso still hasneededForBoot = false, and it has to be true before the wipe lands. -
[ ] Turn off every LED on every piece of hardware in AFK mode. Nothing is declared for this yet (
dead-configconfirms there is no OpenRGB anywhere in the tree). The blocker is the Steel Legend B580's RGB, which OpenRGB does not support: reverse engineering it is a separate, bigger piece of work, and the fans are not controllable at all. -
[~] Passwordless remote maintenance on the router and on the switch (OpenWrt). • ROUTER, done: SSH was already key-based (
ssh v1cferr@192.168.1.1runs in BatchMode), and what was missing wassudo. Today the NOPASSWD ones are/sbin/reboot,/usr/sbin/nft,/sbin/uci,/etc/init.d/dnsmasqand/etc/init.d/firewall(this last one came in on 10/08/2026, with the justification and the method in the history). • A DECISION TO KEEP: an arbitrary command STILL asks for the password. Widening it to(ALL) NOPASSWD: ALLwould be the change that actually escalates privilege, since the current ones do not escalate becausenftalready gives the same reach. Only add a binary with a reason, one at a time. •/usr/bin/wg-statuscame in along with them (a read-only wrapper overwg show); the wholewgbinary does NOT go in, becausewg setreplaces a peer key. • MISSING: the SWITCH, which has never been touched. • NONE OF THIS IS MIRRORED:router-synconly covers/etc/config/. Sudoers and the SSH key live outside the repo, and the router's/home/does not even survive asysupgrade. -
[~] Claude Code, what is LEFT of the two accounts (11/08/2026). The structure was declared in
home/shell/claude-code.nixand the entry is in the august history: theclaude-fai/claude-pessoalwrappers,claude-pick, a versionedsettings.json, a sharedprojects/and plainclaudefalling through to FAI. Three ends are still open, and none of them is declarable: • The/loginfor each account. I did NOT restore.credentials.json(neither the one from the Arch backup nor the one in~/.claude): a token is not something you copy with a script, and the Arch one was 7 weeks old, from a machine that is decommissioned. Check later without spending quota:claude-fai doctorsays whether the account is signed in. • PRUNE THE REST OF~/.claude. It stopped being an account and became just the archive, buthistory.jsonl,settings.json,settings.local.json,sessions/,shell-snapshots/andplugins/were left there (~40 MB outsideprojects/). What was worth keeping was copied to~/.claude-fai; the rest is legacy (rule 16). DO NOT PRUNE BEFORE the new account proves it walks: until the FAI/loginhappens, those leftovers are the only place where that account's state exists. And NEVER touchprojects/, which is the archive, the target of both accounts' symlinks. (A third bullet lived here until 16/08/2026: the header ofsystem/services/claude-code.nixclaimed the user'ssettings.json"CANNOT become a symlink", which read as contradicting the module that links it. The rule 2 sweep rewrote that header, so the drift is gone.) -
[ ] The Azure MCP has nothing to work ON yet (14/08/2026). The server is declared, connected and authenticated (see the august history), but its 68 tools operate over a SUBSCRIPTION, and the day-to-day tenant (
FAIUFSCar) is a directory only:azmcp subscription listanswers 200 with an EMPTY list. Who has a subscription is theBHStenant, and getting into it requires MFA:az login --tenant 92247c24-8a8c-47f3-a7f1-85df939ad4b6, which the browser resolves. Only after that is it possible to say whether the MCP pays for itself here or whetherazalone would have been enough; until then it is ALIVE and IDLE, which is different from broken. The App Registration does NOT depend on this: it already works throughaz adon FAIUFSCar, which was the goal. -
[ ] Release jump 26.05 to 27.05 (~may/2027). It is NOT a reinstall: it is TWO STRINGS in flake.nix,
nixpkgs.url(nixos-27.05) andhome-manager.url(release-27.05), which change TOGETHER (the HM release branch matches the base, otherwise there is an option mismatch). The other ~9 inputs haveinputs.nixpkgs.follows = "nixpkgs"and come for free: the dedup that already exists because of the lock size is what makes the jump trivial, 1 input changes and 9 follow. Without it, each flake would drag its own nixpkgs 26.05 and I would end up with two bases coexisting after the jump.upgradeNEVER makes that jump, and that is a feature:nix flake updateonly moves INSIDE the pinned branch, and intonixos-26.05only BACKPORTS come, cherry-picked CVE/bugfixes that a maintainer marks with thebackport release-26.05label. A new package version does NOT come in, except for the browser and the kernel (upstream only gives security support to the new version, so backporting a Firefox patch would mean rewriting Firefox). Andnixos-26.05(the channel) is notrelease-26.05(the branch): the channel is a pointer that only advances after Hydra builds and the test suite passes, the same gating as nixos-unstable. ThestateVersionDOES NOT CHANGE, not on the jump, not ever. It stays "26.05" forever in hosts/nixos-kingston/default.nix and home/default.nix. The name misleads: it is not "the version of my system", it is "the NixOS version my STATE ON DISK is compatible with". 54 nixpkgs modules read that value, and the canonical case is postgresql.nix, which picks the Postgres MAJOR from it (versionAtLeast stateVersion "26.11"gives postgresql_18; "25.11" gives postgresql_17, and so on). Bumping it makes the module point at a major that does NOT READ the existing datadir: the service does not come up, and if something reinitializes the cluster the database is gone. A generation rollback does not save you: it brings back the SYSTEM, not the /var/lib that was already touched (the same class as the cutover damage, when copying /var/lib broke Docker/Postgres/Sunshine silently). That is why it exists in the config even being immutable: it is the state's BIRTH CERTIFICATE, not a button, and the modules need to know when the state was born precisely because they cannot migrate it on their own. It only changes if the release notes say so, and together with the manual migration (pg_upgrade and the like). Usenixos-rebuild bootand NOTswitch: it applies on the next boot and the 26.05 generation stays in minegrub as the emergency exit. And wait ~2 to 4 weeks after the release (the branch stabilizes as the backports arrive); the cost of waiting here is low, because what I want fresh already comes throughunstable.*and through the direct upstream inputs. -
[ ] Add the current public IP to Fastfetch?
-
[ ] The webcam's ONE remaining test, and it is a cable (opened 04/09/2026). The viewer and the diagnosis are declared and the camera is recognized, but it does not stream: it fails at the UVC probe control with
-71and reboots itself, and the measurements that rule out the driver, the format, the bandwidth and USB autosuspend are in notes/hardware/webcam.md. It is here and not in a module because the remaining suspicion is not declarable: the camera hangs off a bus-powered USB 2.0 hub that advertises 100 mA, shared with a USB Audio and HID device, and its own descriptor asks for 500 mA. IT IS INTERMITTENT, so ONE result decides nothing: 1 stream came through in 17 attempts on 04/09/2026, and the one that worked left no trace in the log at all. Whatever is tested has to be tested several times, in both directions, or the conclusion is noise. THE SOFTWARE SIDE IS CLOSED, so what is left is four physical steps, cheapest first. The probe for all of them is the same, and it must write to a path the USER owns:v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=3 --stream-to=~/cam.raw, then check that the file is NON-EMPTY, because v4l2-ctl exits 0 even when the stream fails.- Pull the USB Audio and HID device off the hub, leaving only the camera. The only current-budget test that does not need a different port.
- A different port on the same hub.
- A REAR MOTHERBOARD PORT, no hub. This is the decisive one; bus 2, the USB 3 root, has no devices on it at all, so ports are free.
- Boot Windows and open the camera there. That settles "is it the device" without any Linux in the picture: if it fails there too, this is an RMA and not a configuration. The trap to recognize at every step is that the MICROPHONE keeps working the whole time, so "the camera is fine, PipeWire sees it" is not evidence of anything.