Three diagnostic defects from the follow-up audit.
1. The reboot plan was entirely best-effort.
persist_plan discarded the directory creation, the write and every error. The plan file
is the only thing on the host that says when it is going to reboot, so a failed write
produced a scheduler sitting on a timer that nothing could report. It now creates the
directory, writes through a temp file with sync_all and rename, and returns Result.
The plan also outlived its meaning in two places. With reboot.enabled = false the
scheduler exited without touching a plan written when it was still enabled, so status
kept advertising a reboot that would never happen. And after systemd accepted the reboot
request the plan stayed behind, leaving a past timestamp looking pending. Both paths now
clear it; an absent plan is the desired end state, not an error.
2. sysctl status turned a read failure into "file absent".
inspect_sysctl_tuning used fs::read_to_string(..).ok() for both managed files, so an
unreadable file was reported as missing - a diagnostic stating the opposite of the
truth, in the module whose whole job is to report drift accurately. Reads now go through
ManagedFile::read, which distinguishes absent from unreadable, and an unreadable file
produces its own drift reason naming the path and the error.
3. README described the removed ExecStartPre.
It still said the service runs ensure-swap before starting the daemon. The daemon
performs it as the first step of its own startup sequence.
Docs also state explicitly what survives swap.enabled = false, which was implied but never
written: the swapfile, its activation and the /etc/fstab entry all remain, so swap comes
back after a reboot. Only the vm.swappiness persistence is removed.
Acceptance checklist gained seven checks covering the priority-only path not recreating the
file, swap remaining active throughout a resize, foreign-swap rollback, the unreadable
status, and both reboot-plan lifecycle cases.
cargo test --workspace: 179 + 4 passed. clippy -D warnings clean.
wireguard-tools was still declared in Depends and in the runtime package list installed by
tools/build.sh --prepare-runtime-env. Since peer discovery moved to docker exec, no code
path invokes a host-side wg, and check_host_tools stopped requiring it. The declaration
was therefore installing a package the harness never calls and misrepresenting the actual
architecture to anyone reading the control file. Removed from both places.
Three items were carrying #[allow(dead_code)], which is a way of silencing the compiler
about a real question rather than answering it:
- SysctlTuningStatus.desired duplicated data that is already in .current - every
SysctlValue holds both the desired and the current value, so the second Vec was the same
information cloned on every inspect call and read by nobody;
- SysctlValue.managed was always set to true and never read. Ownership is decided per file
by the marker, not per key, so the field encoded nothing;
- unix_now() in the reboot scheduler, along with the SystemTime and UNIX_EPOCH imports it
needed. The module works in chrono NaiveDateTime throughout.
All three are removed rather than annotated. The workspace now builds clean under
-D warnings with no dead_code exceptions anywhere.
cargo test --workspace: 158 + 4 passed. clippy -D warnings clean.
- Полностью переписан swap-модуль в режиме exclusive ownership\n- Добавлены verify/checks, статус фактического swap-state и drift\n- Интегрирован ensure-swap в daemon и systemd ExecStartPre\n- Усилен lock API (таймауты) и применение в traffic/firewall/swap\n- Усилен parser firewall (JSON-first + устойчивый text fallback)\n- Обновлены config validation, runtime tools и default priority\n- Синхронизированы docs и build/package hygiene\n- Удалены member Cargo.lock в пользу корневого lockfile