Commit Graph
100 Commits
Author SHA1 Message Date
Ryan Yin c703b590c1 fix(aquamarine): start network-online.target at boot
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-11 09:56:01 +08:00
Ryan Yin 7c2f52c9d5 fix(mihomo): proxy the Google Play CN API
Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-11-10 08:31:35 +08:00
Ryan Yin ad3923df98 feat(git): reach GitHub through gh over HTTPS on agent hosts
Home Manager now owns ~/.config/gh/config.yml on agent hosts; activation moves an existing one to
config.yml.home-manager.backup.

Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-07 23:16:04 +08:00
Ryan Yin a7787198ce fix(shells): disable the nushell welcome banner without Home Manager
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-07 18:01:01 +08:00
Ryan Yin 2b8274deb1 chore(pyclipsync): update to v0.1.4
Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-06 18:40:09 +08:00
Ryan Yin ba149b5edf revert(niri): restore pyclipsync for QQ's X11 clipboard
Reverts 9152e829: QQ's Wayland window still copies through the X11 CLIPBOARD, which xwayland-satellite cannot bridge, so QQ copies never reached Wayland apps.

Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-06 18:30:56 +08:00
Ryan Yin 34e984fb92 fix(nixpak): give QQ an X11 connection for its clipboard
QQ copies through the X11 CLIPBOARD even with a Wayland window; without an X server it exited on copy. QQ now shares XWayland's display trust, like WeChat.

Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-06 18:26:17 +08:00
Ryan Yin 35155906c1 feat(nix-cache): proxy ustc and cachix, prefer the LAN cache
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-06 17:27:18 +08:00
Ryan Yin 8c2f84404c fix(nixpak): let mpv read the musicfox playback cache
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-06 16:19:14 +08:00
Ryan Yin 0704ba5e21 fix(home): open PDFs from sandboxed apps in Firefox
Assisted-by: DeepSeek Harness (claude-opus-5-5)
2026-11-06 12:03:38 +08:00
Ryan Yin fd0af4c097 feat(go-musicfox): disable track-change notifications
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-06 10:36:22 +08:00
Ryan Yin c796643066 fix(nixpak): let mpv use host /tmp for musicfox IPC
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-06 10:36:20 +08:00
Ryan Yin 1d7b06d163 fix(ai): restart the OpenRGB server on resume
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-05 22:10:40 +08:00
Ryan Yin 9f29b48bf6 fix(ipython): keep in-session history in memory only
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-05 12:38:55 +08:00
Ryan Yin d7c493f5cd chore(agents): drop the dsh-nu plugin
dsh-nu replaced every shell command with Nushell and refused bash/pwsh
syntax before it spawned; in practice the refusals were too noisy. Drop
the flake input, install plain dsh, and remove the docs describing the
Nushell-only shell.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-05 11:46:03 +08:00
Ryan Yin dfa53c71d7 fix(nix): take NUR packages from ryan4yin.cachix.org
58d1af8f dropped the cache while adding the pull-through caches. Without
it a NUR bump rebuilds its npm deps here, and dsh's npmDepsFetcherVersion
2 fixed output includes the packuments the Huawei npm mirror rewrites, so
the build fails NUR's hash check instead of reusing its CI-built output.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-05 11:45:51 +08:00
Ryan Yin 706ec235ee chore(nur): update nur-ryan4yin
dsh 0.2.2-alpha.2 -> 0.2.2-rc.1 and computer-use-linux 0.7.36 ->
0.7.37; cua-driver stays 0.38.0. The nur-packages diff is version bumps
plus regenerated dsh lockfile only, with no module or overlay changes.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-05 09:49:49 +08:00
Ryan Yin c4a00e507c fix(nixpak): pass the session TZ through to sandboxes
ICU takes the zone name from the /etc/localtime symlink target path. A bind
mount turns it into a plain file, which keeps the TZif data but loses the
path, so the only identifier left is the ambiguous "CST" abbreviation that
ICU reads from the file and maps to America/Chicago.

Export TZ from time.timeZone and pass TZ/TZDIR through the nixpak env
allowlist.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-04 21:38:18 +08:00
Ryan Yin 432de26764 feat(agents): add Qwen Code and use OpenCode V2 as opencode
Expose llm-agents' opencode2 package under the normal opencode command and persist Qwen Code's ~/.qwen state on the ephemeral-root hosts.
2026-11-04 00:15:43 +08:00
Ryan Yin 99b0208a2a fix(aquamarine): persist raft state
Preserve ~/.raft across reboots so Raft Computer keeps its enrollment, machine identity, agent state and app data. ~/.local/bin and ~/.config/gh were already persisted.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-03 23:50:45 +08:00
Ryan Yin e3bc8cbe4c chore(nur): update nur-ryan4yin
Update nur-ryan4yin to d82be0b. Audit: only the prebuilt packages cua-driver (0.36.0 -> 0.38.0) and computer-use-linux (0.7.20 -> 0.7.36) changed; the NUR modules and trust-related settings did not move. Only the kana and ruby system closures change.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-03 20:49:06 +08:00
Ryan Yin c4c75a2d8d fix(npm): use the Huawei npm mirror
Only Huawei works with prefetch-npm-deps: npmmirror 404s on its doubled
slash, and Tencent answers 567 to its concurrent fetches (WA-049).

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-03 20:02:39 +08:00
Ryan Yin 4470b3d014 docs: centralize documentation under docs/
Move standalone repository docs from the root into docs/ and add a documentation index that links the moved docs and the code-local runbooks.

Update Markdown links, source comments, and the root entry points to the new locations. Keep README.md and AGENTS.md at the root as required entry points.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-02 17:48:57 +08:00
Ryan Yin 179b20a42c fonts: add Japanese and Korean locale fallbacks
Keep SC as the default and select JP/KR glyphs for lang=ja/ko.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-02 12:06:29 +08:00
Ryan Yin f9ece8167d fonts: prefer Noto CJK family names
Noto CJK and Source Han share the same glyphs; Noto names are more common in Linux.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-02 11:45:12 +08:00
Ryan Yin 1193e20cf0 docs: remove completed C4 cleanup card 2026-11-02 11:16:27 +08:00
Ryan Yin 0f5ad1ad10 fix(aquamarine): socket-activate whisper-asr with FreeBind
At boot whisper-asr could start before the LAN address was configured and
fail with "could not bind on any address". Let whisper-asr.socket bind it
with FreeBind and have uvicorn take fd 3, like the exporters.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin c732f3b9bb refactor(vr): route headset audio with a WirePlumber hook
A default-node hook selects wivrn.sink/wivrn.source whenever they exist,
so the polling wivrn-audio.nu unit, its saved state and `just vr-audio`
go away. Streams follow via linking.follow-default-target.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin be592ae75c refactor(mihomo): link geodata from nixpkgs instead of seeding it by hand
`just mihomo-geo` copied geodata into the state dir so a cold start never
fetched it. tmpfiles now links v2ray-rules-dat and the DB-IP lite mmdbs
there, so geo-auto-update moves to the gateway config only.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin c8bbeb708d refactor(overlays): get NUR packages from the nur-ryan4yin overlay
myNurPkgs evaluated a second nixpkgs just for four packages. Apply the
NUR repo's own overlay instead, so they come from the host's pkgs.

Darwin's pkgs now gets nixpkgsConfig too: it set nixpkgs.pkgs, which
ignores nixpkgs.config, so only myNurPkgs carried the npm mirror there.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin 70d8bd6791 refactor(shoukei): drop dead nettle and qemu-user static overlays
Both only touch pkgsStatic builds, which nothing on this host pulls in
since qemu-user binfmt was removed; the toplevel drvPath is unchanged.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin 6ea53e8dd7 refactor(darwin): decrypt agenix secrets to /etc/agenix via path
agenix's darwin module honours age.secrets.<name>.path and applies owner and
mode itself, so the environment.etc links and the postActivation chown/chmod
that re-applied them go away.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin 3789a2a282 chore(nixos): guard the nix and xdg-desktop-portal-wlr pins at eval time
WA-023 warns once nixVersions.stable reaches 2.35; WA-046 fails the build
once nixpkgs' xdg-desktop-portal-wlr is no longer the broken 0.8.4, so both
pins get revisited instead of lingering.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin eaa53004e5 fix(aquamarine): install only clr's OpenCL ICD instead of the openvino-gpu wrapper
hardware.amdgpu.opencl.enable also adds clr, whose OpenCL 2.2 libOpenCL.so.1
lands in /run/opengl-driver/lib, first in OpenVINO's RUNPATH, and shadows the
ocl-icd loader the GPU plugin links. With clr.icd alone the plugin finds
ocl-icd, so the wrapper and WA-038 go.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin fe280d8fa2 refactor(ssh): drop no-op openFirewall
It is already the sshd module default, and the shared firewall forces
allowedTCPPorts to [ ] anyway; toplevel drvPaths are unchanged.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin 04a8438bd3 refactor(canokey): rely on systemd uaccess rules instead of custom udev
systemd's 60-fido-id.rules marks the FIDO hidraw node and the CCID USB
device as security tokens, and 70-uaccess.rules grants them to the
active seat. Drop the hand-written rules and the plugdev membership.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin 4ecb7c475e fix(git): back up a stray ~/.gitconfig after writeBoundary
Move it aside with HM's `run mv` (dry-run aware) instead of an
unconditional rm before checkLinkTargets.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin ce49b03014 fix(monitoring): socket-activate LAN exporters with FreeBind
Exporters raced networkd for the LAN address at boot; drop the
network-online ordering and unlimited-restart hack and let a FreeBind
socket unit hold the port, passed in via --web.systemd-socket.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:55:14 -06:00
Ryan Yin b063feca29 chore(youko): drop victoriametrics' leftover data-dir group
The data dir is the module's own DynamicUser StateDirectory (already
/var/lib/victoriametrics -> private/victoriametrics on youko), so the
victoriametrics-data group, its tmpfiles rule and SupplementaryGroups
did nothing. stateDir was set to its default.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 64c465660c refactor(youko): create the /data-ro mountpoints in initrd tmpfiles
Root is tmpfs, so the backing dirs must exist before the /data bind
mounts. initrd tmpfiles rules on /sysroot do that before switch-root,
replacing the activation script.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 6fa6e6626e refactor(youko): run homepage from the native NixOS module
services.homepage-dashboard runs the nixpkgs package with DynamicUser,
replacing the :latest container, its system user and the activation
script that rsynced the YAML into place. The YAML stays as is and is
linked into /etc/homepage-dashboard.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin c8d8b17a27 refactor(youko): link caddy's wallpapers with tmpfiles
A tmpfiles L+ symlink to the store path replaces the activation script
that rsynced it on every switch. Files that were removed upstream no
longer linger.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 5c9bb6f95f chore(shoryu): drop the libvirt default-network oneshot
NixOS's libvirtd-config copies default.xml but never creates its
autostart link, and shoryu has no networks/autostart directory at all,
so virbr0 never starts and the oneshot had nothing to disable.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin f520c992d5 refactor(youko): order transmission-netns after the br0 device
Replace the 30 s `ip link show br0` poll with BindsTo/After on
sys-subsystem-net-devices-br0.device.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 8d32297dcd refactor(ai): reset the Insta360 Link on resume via a usbcore quirk
USB_QUIRK_RESET_RESUME ("b") makes usbcore reset the camera instead of
resuming it, and uvcvideo implements reset_resume, so the resume hook
that ran usbreset after S3 is no longer needed.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 8084f25e6f refactor(youko): disable HDD spindown from a udev rule
Apply hdparm -B 255 -S 0 whenever a disk appears, which also covers the
re-add after a bridge reset, instead of a boot oneshot plus an hourly
timer. Drop -J 0: hdparm has always aborted it without
--please-destroy-my-drive, and wdidle3 already reads disabled on both
disks (it is persistent firmware state).

This was the last user of mylib.systemdHardening.privilegedOneshot, so
remove the preset and its test group.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin f8ca25a03b refactor(power-monitoring): grant RAPL read access from a udev rule
The boot-time oneshot only fixed the zones present when it ran, and
node_exporter had to Require it. A powercap add rule covers every zone
whenever it appears; the collector reads at scrape time, so no ordering
is needed.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 42341491f3 refactor(shoukei): cap battery charging from a udev rule
macsmc-battery's "add" uevent fires before the supply accepts writes
(power_supply_register bumps use_cnt after device_add); its deferred
register work then emits "change". Match both instead of polling for 30 s
from a oneshot.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin ecf242d6ab refactor(aquamarine): cap the R9700 power limit from a udev rule
amdgpu registers power1_cap with its hwmon device, so a rule on each
card's hwmon add event replaces the oneshot that polled /sys/class/hwmon
for 60 s waiting for both cards to probe.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 11:42:57 -06:00
Ryan Yin 2036b97f85 docs(workarounds): put WA-048 back in the table
It was wrapped across lines after a blank line, so it rendered as a
paragraph. Text unchanged.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin 7c0b5fc0b8 fix(mihomo): keep the proxy up when the resolved hook times out
On shoukei a DNS takeover that timed out failed mihomo.service, and the
nixpkgs unit has no Restart=, so the proxy stayed down. Prefix the hook
with '-' (fail open, like ai's hook). Also switch the dashboard title
patch to --replace-fail.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin 201070155a fix(homepage): drop the weather providers block that never worked
A 2024 formatter pass turned `{{…}}` into a YAML flow map, the variable
was never passed to the container, and no widget uses it.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin 8b22aec1bb fix(restic): drop a stale btrfs snapshot before taking a new one
Cleanup runs as ExecStopPost, which a power loss mid-backup skips; the
leftover @restic-snapshot then failed every later run.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin 32620ed9db chore(aquamarine): drop pcie_aspm=off
It was a precaution for the R9700 links, never an observed problem, and
on BIOS 1013 the FADT already disables ASPM ("ACPI FADT declares the
system doesn't support PCIe ASPM"), so the parameter did nothing.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin dd2bd44bc2 fix(youko): apply /data tmpfiles in a pass of their own
89d7a9bd made systemd-tmpfiles-setup RequiresMountsFor the five nofail
USB-disk mounts. One failed mount then skipped every tmpfiles rule on the
host, and sysinit.target waited for the disks and the LUKS unlock even on
success.

Leave the boot-wide pass as upstream ships it and add data-tmpfiles:
`systemd-tmpfiles --prefix=/data` with WantsMountsFor on the /data mounts,
ordered before the services that use them.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:51:51 -06:00
Ryan Yin 905c3c6e1f docs(workarounds): retire WA-017, clarify WA-026, refresh WA-023
- WA-017: keyd(1) documents `control = layer(control)` etc. as the
  default modifier bindings, so a keyd bump will never keep right-hand
  modifiers distinct; the passthrough is intentional config. Say so in
  peripherals.nix and drop the row.
- WA-026: installOnHost + restarting microvm@<guest> is the fallback
  microvm.nix's own deploy.rebuild uses; only the in-place sshSwitch is
  broken, so the removal condition is now about that.
- WA-023: locked versions are 2.35.3 (latest) and 2.34.9 (stable).

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin e4c2548a93 refactor: replace redundant mkForce with plain values and mkDefault
Each of these overrode a value nothing else set at a higher priority:

- qemu-guest: btrbk, hardwareTools and cloud-init have no competing
  definition on the guests.
- mdns: nixpkgs' sunshine module sets avahi.publish.* with mkDefault.
- computer-use: i18n now sets the time zone with mkDefault.
- darwin terminal: the shared ghostty/kitty font sizes are now mkDefault.
- shoukei: sunshine is mkDefault false in remote-desktop.nix, zram's
  memoryPercent is mkDefault 50; supportedFilesystems now merges instead
  of discarding the fsType entries other modules add.
- youko: nothing enables docker.
- nixpak: pasta.enable and sockets.pipewire are mkDefault in the shared
  modules, sockets.pulse already was.

Every NixOS host's toplevel drvPath is unchanged; on fern and frieren the
terminal font sizes and time zone evaluate to the same values.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin 4bd428776e fix(darwin): pass the Homebrew mirror env through onActivation.extraEnv
nix-darwin runs `brew bundle` as `sudo --preserve-env=PATH ... env ...`,
so the variables the mkBefore'd activation snippet exported never reached
brew; activation was using the default upstream endpoints. Set them via
homebrew.onActivation.extraEnv, which nix-darwin puts on the `env` command
line (evaluated on fern), and drop the snippet.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin a5fac14ab3 docs(workarounds): drop WA-034, removed with the gateway's fake-IP IPv6
bb899876 moved the proxy gateway to fake-IP for IPv6 and removed
aquamarine's getaddrinfo precedence table, so the row's removal condition
has been met since 2026-10-14; only the row and a comment pointer lingered.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin f7a92ac704 chore(nvme): drop default_ps_max_latency_us=100000, the kernel default
drivers/nvme/host/core.c defaults default_ps_max_latency_us to 100000, so
the "relaxed" APST cap on ai and its copy on aquamarine set the value the
kernel already uses. Keep ai's history and rollback recipe as a comment,
and stop the aquamarine pcie_aspm=off comment from citing WA-008, which
never covered it. Removes WA-008.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin b5c573592b chore(ai): drop the nvidia-drm.fbdev kernel param the module already sets
hardware.nvidia.modesetting.enable makes nixpkgs' nvidia module add
nvidia-drm.modeset=1 and, for drivers >= 545, nvidia-drm.fbdev=1 to
moduleParams, which reach modprobe via extraModprobeConfig (evaluated:
"options nvidia-drm fbdev=1 modeset=1" on ai with 595.x).

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin 455c03d1fd chore(security): drop the Comodo AAA root blacklist both platforms now carry
nixpkgs' security/ca.nix and nix-darwin's security/pki module both append
"Comodo AAA Services root" to the cacert blacklist themselves, so the
explicit entry only duplicated it. Removes WA-040.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin 1904323e38 chore(tuios): use the nixpkgs package instead of the upstream flake
nixpkgs packages tuios 0.11.1, the same tag the flake input pinned, so
the extra input (and its nix-fast-build/treefmt-nix lock entries) only
duplicated it. Removes WA-005.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin 993dbee7ab chore(smartctl-exporter): drop the #329 pin now that nixpkgs ships 0.15.0
nixpkgs packages smartctl_exporter 0.15.0, which contains PR #329. The
overlay pinned 6274decc ("0.14.0-unstable-2026-09-28"), so it had been
downgrading the package since the last nixpkgs bump. Removes WA-001.

Assisted-by: Claude Code (claude-opus-5-5)
2026-11-01 10:14:27 -06:00
Ryan Yin 88ff500dfc chore(wechat): use nixpkgs-master now that NixOS/nixpkgs#560225 is merged 2026-11-01 23:34:00 +08:00
Ryan Yin a97400df69 fix(systemd): sandbox privileged hardware oneshots
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-01 20:49:51 +08:00
Ryan Yin e0cb3eab75 fix(grafana): restore datasources and GPU power metric
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-01 20:49:05 +08:00
Ryan Yin 9fe86de51d flake.lock: Update
Flake lock file updates:

• Updated input 'llm-agents':
    'github:numtide/llm-agents.nix/e452052b9efb54fd59f8a06cbc09978fb542a3c2?narHash=sha256-pU0HWLzBuoGIYLMIjoZNqiALCAUl9JwV6ujIyOZO3i4%3D' (2026-10-29)
  → 'github:numtide/llm-agents.nix/8efcba308a6b12a92441cb4df624e484bad9e18a?narHash=sha256-i4UBJIugcPJxG4xKnlsypbTb8QfPX%2BkagQYF9oswO/c%3D' (2026-11-01)
• Updated input 'llm-agents/nixpkgs':
    'github:NixOS/nixpkgs/e62746b0b472753ef019baceab6f1e2e52014980?narHash=sha256-sx1f99WGrDfJ83KKuQrqGPmot0rnDgmpLJDzpU2oHQQ%3D' (2026-10-28)
  → 'github:NixOS/nixpkgs/885ba4d038f10c3d17d7a92e8c3cc185b99c9158?narHash=sha256-e/yiZ31gXRROBDcnOtT3YwDQ73NVG9Cepccbt86LIn8%3D' (2026-10-30)
2026-11-01 16:58:11 +08:00
Ryan Yin af084f1eb4 feat(npm): use npmmirror for npm fetches
Set the user-level npm/pnpm registry to npmmirror, and make Nix builds use the same mirror through nixpkgs' npmRegistryOverrides and rewriteURL. The configured Nixpkgs policy is also applied to myNurPkgs and Colmena's nodeNixpkgs so NUR packages such as dsh use the mirror while preserving Colmena parity.
2026-11-01 16:57:57 +08:00
Ryan Yin 5e5ceae108 docs(nixpak): record slicer runtime validation 2026-11-01 11:52:08 +08:00
Ryan Yin 98d1c2d6e7 fix(nixpak): allow WebKit network portals for slicers 2026-11-01 11:46:58 +08:00
Ryan Yin d54b49b799 docs(nixpak): document intentional Firefox media limits 2026-11-01 10:49:52 +08:00
Ryan Yin 7a00fead7d fix(tuios): force xterm-kitty inside panes 2026-11-01 09:43:04 +08:00
Ryan Yin 9152e82916 chore(niri): remove pyclipsync clipboard bridge
WeChat and QQ now use native Wayland, so the X11/Wayland clipboard bridge
is no longer needed. Remove the flake input, home-manager module wiring,
lock entries, and stale documentation reference.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-01 09:37:15 +08:00
Ryan Yin 87b7a23cf3 docs(nixpak): consolidate runtime validation notes
Merge the three runtime-validation files into one concise record, update the interactive browser and Zoom results, and document the intentional Chromium host-loopback and Brave/Edge no-media exceptions. Tighten the remaining cookie-crypto workaround and the smoke-test prerequisites.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-11-01 09:24:23 +08:00
Ryan Yin 30cb22500f fix(niri): route Zoom screen sharing through xdg-desktop-portal-wlr 0.8.2
niri 26.04 exposes DMA-BUF only, which Zoom 7.2.1 rejects. xdg-desktop-portal-wlr 0.8.2 provides the working SHM path; 0.8.4 regresses Zoom SelectSources.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-31 22:44:16 +08:00
Ryan Yin 56edac8252 fix(transmission): grant the AppArmor lock permission
nixpkgs' transmission 4.1.4 profile grants rw on the daemon's config directory
but not k, while 4.1.4 takes a fcntl lock on
~/.config/transmission-daemon/lock, so the daemon exited at startup with
"Another process is already using". Include rwk for that one file only.

WA-044, drop once the nixpkgs profile carries the permission.

Assisted-by: Claude Code (claude-opus-5-5)
2026-10-31 01:09:16 +08:00
Ryan Yin 560a6cc2d8 fix(preservation): mount /etc/ssh in initrd so key changes apply on boot
NixOS copies mode-carrying /etc entries such as authorized_keys.d during
stage-2 activation, which runs before systemd starts. preservation mounted the
persisted /etc/ssh from preservation.target afterwards and hid that copy, so a
key change only took effect on `switch`: revoking a key and rebooting silently
restored the old one.

Prepare the mount in initrd, before activation runs, and cover it with a VM
test that seeds a stale authorized_keys file, reboots, and asserts the declared
key replaced it. The same test fails on that assertion with inInitrd disabled.

Verified on all four hosts: /persistent/etc/ssh/authorized_keys.d/root is now
rewritten at boot instead of keeping the timestamp of the last switch.

Assisted-by: Claude Code (claude-opus-5-5)
2026-10-31 01:09:16 +08:00
Ryan Yin 7dc4e7a39f feat(security): harden homelab SSH, services and audit trail
The homelab hosts accept root SSH with long-lived file keys, run several
exposed services with almost no systemd sandboxing, and keep no audit trail of
privileged actions. Close those three gaps, weighing each measure against its
cost instead of adopting a policy wholesale.

SSH
- Turn off KbdInteractiveAuthentication: nixpkgs defaults it to true and PAM
  then still accepts the Unix password despite PasswordAuthentication = false.
- authorizedKeysInHomedir = false: only keys declared in Nix take effect;
  youko keeps Gitea's forced-command file through `Match User gitea`.
- Pin aquamarine's passphrase-free remote-builder keys to
  `restrict,command="nix-daemon --stdio --store daemon"`, so builds run in the
  system daemon instead of an audited root login session.

systemd sandboxing
- Add the mylib.systemdHardening preset and apply it to the exposed, weakly
  sandboxed services: caddy 7.8 -> 1.5, vmalert 8.2 -> 1.4, rustfs 6.6 -> 1.4,
  whisper-asr 7.7 -> 1.6. An eval test pins the key restrictions.
- Rejected: a global all-keys policy (<=0.2 score gains on services nixpkgs
  already sandboxes) and per-service confinement (bind paths to maintain).

auditd on all four hosts, reusing nixpkgs' loader and unit
- Audit login sessions only: a first `-a never,task -F auid=unset` rule keeps
  services out of the per-syscall audit path. A compromised service is
  therefore unrecorded until it opens a session.
- Record root commands, credential and host-key access, writes to SSH, account,
  PAM, Nix-trust and audit configuration, module loads and session denials.
- Rejected: global denial logging, service-UID watches and
  --loginuid-immutable (the kernel already records loginuid changes).

Verified on all four hosts after deployment: zero failed units, k3s 6/6 Ready,
and the exposed services healthy.

Assisted-by: Claude Code (claude-opus-5-5)
2026-10-31 01:09:15 +08:00
Ryan Yin 0376697cef docs(agents): record why rules omit principle names 2026-10-30 18:59:09 +08:00
Ryan Yin def7d8f754 feat(niri): enable on-demand VRR for games
Turn on adaptive sync at the output only when a game window opts in, keeping desktop compositing fixed-rate to avoid idle/low-load VRR flicker. The Steam/Proton game rule enables VRR alongside the fullscreen rule.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-30 00:47:51 +08:00
Ryan Yin 005627d883 fix(niri): let untitled Proton windows go fullscreen
XWayland/Proton windows can commit before they set a title. Excluding empty titles made Phantom Blade Zero miss the fullscreen rule and stay composited. Keep excluding the launcher announcement popup by title.

VRR is intentionally not enabled here: on-demand VRR caused display corruption in this game and is tracked separately.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-30 00:46:22 +08:00
Ryan Yin 4fcdb79719 docs(agents): answer challenges before continuing work
A user question or challenge is the current task; resolve it before doing unrelated work.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-29 21:40:46 +08:00
Ryan Yin ba1515f094 docs(agents): ask for SSH access instead of falling back
A missing GitHub SSH key is a credential boundary, not a reason to switch transports silently.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-29 21:39:16 +08:00
Ryan Yin 13afe01441 docs(agents): prefer upstream fixes over local workarounds
Clarify that minimality means the smallest best-practice change, not a local patch around an upstream defect.

Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-29 21:37:41 +08:00
Ryan Yin 7e579d6aca fix(monitoring): order nvidia exporter after network-online
The nvidia exporter binds the host's static LAN IPv4, but unlike the node and smartctl exporters it was not ordered after network-online.target. On boot it lost the race with networkd, hit the systemd start limit, and stayed failed until manually restarted.
2026-10-29 21:28:08 +08:00
Ryan Yin 01d2e76410 chore(secrets): refresh mysecrets and follow agenix-rules rename
Update the mysecrets lock to 7f93490, which renames secrets.nix to agenix-rules.nix, drops the deprecated ./ key prefixes for agenix 0.18, and re-encrypts the access-token secret. Update the docs and agenix skill to the new filename and path convention.
2026-10-29 21:28:08 +08:00
Ryan Yin 38d1d85e85 feat(home): re-add gitleaks
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-29 17:04:39 +08:00
Ryan Yin 8a6cc86664 docs(agents): stop on credential failure
Assisted-by: DeepSeek Harness (deepseek-flash)
2026-10-29 15:55:30 +08:00
Ryan Yin add8ad9796 chore(home): remove VS Code 2026-10-28 13:51:16 +08:00
Ryan Yin bd41cca5c6 fix(grafana): correct alertmanager dashboard description typo 2026-10-28 13:51:16 +08:00
Ryan Yin b334336cd9 feat: idols-ai - persistent ~/models 2026-10-24 17:16:20 +08:00
Ryan Yin c562f47049 docs(workarounds): drop WA-043 now that the bootstrap fix is live
k8s-gitops#54 merged and reconciled, a full cold start of all six guests
brought the VIP back without manual action, and a probe from a pod shows
2379 denied while 2381 stays open. SECURITY.md records the fix and the
probe; the workaround row and its TODO entry are gone.

Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-10-24 14:26:53 +08:00
Ryan Yin 8affae69d6 docs(security): record the 2026-10-22 audit follow-up and WA-043
Baseline sysctls, exporter binds and the #399/#400/#401 rules verified
live on 13 hosts; kiali self-escalation and the list-vs-get probe blind
spot recorded; WA-043 registers the k3s-test-1 Cilium/kube-vip bootstrap
cycle (WA-040 is the Root CA blacklist row); the TODO table gains the
cluster-recovery line. The same section records the manual recovery and
its fix in k8s-gitops, plus the 2026-10-24 full cold start that brought
the VIP back without manual action; WA-043 drops when #54 merges.

Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-10-24 14:16:14 +08:00
Ryan Yin 5088535ac3 fix(ai): bind the nvidia GPU exporter to the static LAN IPv4
The 2026-10-22 audit found the live socket on *:9835: #373 bound
node/smartctl in monitoring.nix, but the nvidia exporter enabled in
hardware-nvidia.nix kept the nixpkgs default, so the socket-level
defence-in-depth layer never existed for 9835.

Extend the security-exporters eval check to every enabled exporter's
listenAddress so a future exporter without a bind fails the test.

Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-10-24 14:16:14 +08:00
Ryan Yin d4aa25d368 fix(k3s): deny pod sources the etcd client port 2379
The etcd client API listens on the masters' static LAN address, and the
pod-source deny lists omitted it. Add 2379 to both nft drop lines and
assert it in the security-k3s-pod-firewall eval test. 2381 (etcd
metrics, scraped by in-cluster monitoring) stays reachable by design.

Pairs with the matching Cilium egressDeny port in k8s-gitops.

Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-10-24 14:16:14 +08:00
Ryan Yin f564807ac5 fix(preservation): persist OpenRGB settings and profiles
Assisted-by: DeepSeek Harness (gpt-6-astra)
2026-10-23 11:29:45 +08:00
Ryan Yin cfafc94666 chore(modules): drop the riscv64 module, which belongs to nixos-config-sbc
Nothing imported it and the riscv64 output was already commented out; riscv64 hosts live in ryan4yin/nixos-config-sbc.

Assisted-by: DeepSeek Harness 0.2.1-rc.2 (deepseek-flash)
2026-10-22 00:54:27 +08:00
Ryan Yin cf34f52af0 flake.lock: Update
Flake lock file updates:

• Updated input 'dsh-nu':
    'github:ryan4yin/dsh-nu/c7c0b2ca8fcd6fd5791823d6ed2a8f37e817b275?narHash=sha256-Ua5VKHzb7iobq%2B6P7Q8t/2U8t%2BheFmdXl5zIQB4hJGI%3D' (2026-10-21)
  → 'github:ryan4yin/dsh-nu/405e24541f8ea1c99bde545689e3d22819efe4ac?narHash=sha256-K95TJliFJrD3ssB9jMEqEQ3R7qJtK5wd6tK9oy5ZZ9E%3D' (2026-10-21)
2026-10-22 00:54:27 +08:00
Ryan Yin 75a98e5f66 docs(agents): say that pushes need authorization
Assisted-by: DeepSeek Harness 0.2.1-rc.2 (deepseek-flash)
2026-10-22 00:54:27 +08:00