# felhom.eu — task reports > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). ## SPIKE — NAS verify mechanisms + NFS squash matrix — 2026-07-11 **Class:** spike (findings doc is the only artifact; no production code touched). **Record:** `documentation/audits/SPIKE-nas-verify-2026-07-11.md`. **Baselines (read-only):** felhom-agent `300f06722b` (v0.80.0, `netmount.go` = recipe under test), felhom-controller `3db9126121` (v0.112.0, the probe container), felhom.eu `8ca1272db6`. ### Verdicts (all five questions answered live, evidence in the record) - **Q1 — in-guest automount trigger: PASS (make-or-break).** A `pct exec` ls AND a docker bind-mount access from inside guest 9201 both wake the host systemd automount (~1 s); content correct, nfs4 propagates host→guest; idle-unmount + re-trigger proven. Q1c open item: whether a trigger installed BEFORE guest start carries through at boot needs a restart-window test (no restart permitted this spike). - **Q2 — controller uid-1000 probe: PASS.** `docker exec -u 1000:1000` chain proof + `setpriv --reuid 1000` mechanism proof (same syscalls as `syscall.Credential`); CapEff `a80425fb` has SETUID/SETGID; server-side files land `101000:101000`. - **Q3 — Route A: ACCEPTED-with-caveats.** `all_squash` to an arbitrary server uid (1050) gives the guest-uid-1000 app full read/create/rename/**hardlink**/delete. Caveats: guest sees `nobody:nogroup`; `chown` fails immediate-clean EPERM; `chmod` SUCCEEDS and persists server-side. q3c pinned the June WRONG case: `anonuid` without `all_squash` never applies to non-root traffic — wire uid 101000 fails on others-perms. Consumer guidance must require the "map/squash ALL users" mode, not just an anon-uid field. - **Q4 — error taxonomy + timing:** full table in the record. Headlines: NFSv4 returns the IDENTICAL `No such file or directory` for nonexistent vs not-permitted exports (merge those error categories); dead server = systemd `timeout` at **90 s** (systemd kills mount.nfs before its 2-min retry — no diagnostic string); **`retry=0` recommended for the PRODUCTION unit** (dead-server verify 90 s→3.1 s with clean `No route to host`; guest on-demand access 91 s→3.8 s ENODEV; happy path untouched; autofs retries fresh per access). SMB splits cleanly: `error(13)`=credentials, `error(2)`=share name. **Budget (Q4-vii):** verify cannot ride the agentapi global 15 s timeout (`client.go:87`) — worst case is systemd's 90 s; give AddNetStorage its own longer-lived path or async status-poll, ~120 s end-to-end, agent-side `systemctl start` bounded at ~95 s. - **Q5 — plain-user SMB: PASS.** Stock user + rw share, zero server-side uid config, all 8 probe steps pass INCLUDING hardlink (on Debian Samba/ext4 — re-verify on a real appliance); server-side ownership = the authenticated account; guest sees forced `1000:1000/0664`. ### Safety rails held Isolated scratch root `/srv/nas-spike2/` on 180 (backups `.bak-nasspike2`); no iptables/network manipulation (unreachable case = verified-unused 192.168.0.199); no guest restart; spike mounts only under `/mnt/felhom-drives/spike2-*`. **Teardown verified:** exports back to pre-count 2, smb.conf sections 6, spike users/scratch/units/creds/mountpoints all gone, 0 spike2 mounts on host and in guest, controller 0.112.0 healthy, spike-pulled alpine image removed. **Next:** the production "NAS verify-before-commit + UI redesign" TASK is written by the operator side on these findings (STOP honored — no production work started).