Kill switch fails closed: a present-but-unreadable override at first load
or a non-boolean enabled turns the router off (logged); /route reload says
when the previous config was kept. Prompt rules with nested quantifiers
are dropped; a config path that is not a regular file reads as failed;
caught errors log kind + code only (errWord); rejected keys are masked in
logs (keyWord), alias keys match KEY_NAME, prototype names are never keys;
offers capped at 256; a models alias without a fallback list is ranked at
the end of the default chain; canonical matches a table id at a '-'
boundary only; logCall/noteMain cannot unroute a step; route-tool failure
text no longer claims nothing was routed.
Repo side: mods suite probes the 'claude plugin test' usage line, doctor
bounds plugin list to 60 s, update-all skips @skills-dir mods.
Kit 431/431, full make test green.
Tracked relative symlink skills/model-router -> ../mods/model-router: Claude
Code loads the mod in place as model-router@skills-dir wherever link.sh
links ~/.claude/skills (no CLAUDE_CODE_PLUGIN_DIRS: absolute paths in the
tracked settings.json). Engine-laid mods/*/tsconfig.json gitignored.
lib/tests/mods.test.sh: manifest name, link target, claude plugin validate
and test per mod, capability-probed, time-bounded, SKIP with reason.
doctor.sh: fail-soft Mods section (link by -ef, one guarded plugin list).
CLAUDE.md: mods/ section (loading, per-machine enabled:false switch,
dev-copy shadowing, tests).