Enforces the rails the vault depends on: only directories are linked
(agent editing tools refuse to write through a symlinked file), a missing
target is refused rather than turned into a dangling link, and adopting a
populated live directory copies without clobbering.
Also fixes slug sanitization in _agents_repo_slug to apply the same
[^a-z0-9._-] → - mapping to the fallback (no-remote) branch, ensuring
local project slugs are filesystem-safe and won't leak special chars like
spaces or exclamation marks.
Keys a project by its remote rather than its path so the key survives a
machine change or a directory rename. Falls back to a path-derived
local-* key when no remote exists.
Adds a hermetic test harness that builds throwaway repos under mktemp.
Adds tests/run-tests.fish (syntax lint over every .fish file, plus a
sandboxed interactive load) and tests/functional.fish (10 checks
covering XDG/PATH/CDPATH setup, key bindings, abbreviations, core
functions, exit rewiring, and the opinionated-component registry).
The sandbox copies config-relevant files into a scratch HOME/XDG tree
rather than symlinking the checkout, since this repo also serves as a
live ~/.config/fish and a symlink would let universal-variable writes
leak into the real fish_variables file.
Wires the suite into build-docs.yml as a `test` job that `build-docs`
now depends on, so a broken config can no longer get published to the
docs site. Documents the workflow in the README's new Testing section.