Skip to content

test: every linked config must belong to a tool - #60

Merged
YASoftwareDev merged 1 commit into
masterfrom
test/config-needs-tool
Sep 20, 2026
Merged

YASoftwareDev merged 1 commit into
masterfrom
test/config-needs-tool

Conversation

@YASoftwareDev

Copy link
Copy Markdown
Owner

What

Every config directory the install links must declare how its tool is obtained:

policy meaning
installer the repo provides the tool (function named and verified to exist)
guarded the linking path tests has <tool> first
prerequisite declared here WITH a reason

An undeclared config dir fails, so nobody can add config for an uninstalled tool
without saying so.

Why

The no-sudo tmux bug was never "tmux was missing". It was the repo linking tmux
config and cloning tmux plugins for a tmux that was not there
, so a host looked
configured while nothing could use it. 1.13.2 fixed that instance by hand. Nothing
stopped the next one - and tests/no-fixture-masking.py cannot see this class at
all, which it states in its own output. This is the other half.

Current state, all six linked dirs declared and verified:

git       tool=git    policy=prerequisite
nvim      tool=nvim   policy=installer
ripgrep   tool=rg     policy=installer
tmux      tool=tmux   policy=guarded
yazi      tool=yazi   policy=installer
zsh       tool=zsh    policy=guarded

Why a table and not inference

Two things are not inferable, and pretending otherwise is how a checker becomes a
placebo:

  • A dir name does not name its tool - ripgrep/ configures rg.
  • "Is this a fair prerequisite?" is judgment. git is one because you cannot
    obtain this repo without it; the script must not decide that itself.

The table also names the function to verify. Inferring it was wrong three ways
on the first run - install_neovim not _install_nvim, _install_ripgrep not
_install_rg, and zsh's guard lives in install_zsh while the symlink is one call
away in _link_zshrc. That produced three false findings against entirely correct
code. Declaring the name is honest; guessing was not.

Red-proof

Each mutation rc=1, control rc=0:

mutation finding
remove the 1.13.2 tmux guard 'tmux' claims policy 'guarded': install_tmux() does not test \has tmux``
add an undeclared config dir config dir 'newtool' is linked but not declared in POLICY
rename a declared installer 'ripgrep' claims policy 'installer' via _install_ripgrep(), which does not exist

Limit, printed in its own verdict

guarded is recognised by a has <tool> test inside the named function or one call
away. A guard written another way reads as absent, and deeper call chains are not
followed. Stated rather than silently approximated.

Verified

test.sh workstation 62/63, 0 failures; lint-workflows PASSED;
ci-gate-covers-all passes (no new job); no-fixture-masking PASSED.

The no-sudo tmux bug was not "tmux was missing" - it was the repo linking
tmux config and cloning tmux plugins for a tmux that was not there. 1.13.2
fixed that instance by hand; nothing stopped the next one.
no-fixture-masking.py cannot see this class, and says so in its own output.

Each config dir the install links must now declare one of: installer (the
repo provides the tool), guarded (the linking path tests `has <tool>` first),
or prerequisite WITH a reason. An undeclared config dir fails, so a new one
cannot be added without stating intent - the mapping is a table rather than a
heuristic, because a dir name does not reliably name its tool (ripgrep -> rg)
and "is this a fair prerequisite" is judgment this script must not fake.

The table also names the FUNCTION to verify. Inferring it was wrong three
ways on the first run - install_neovim not _install_nvim, _install_ripgrep
not _install_rg, and zsh's guard sits in install_zsh while the symlink is one
call away in _link_zshrc - producing three false findings against correct
code. Declaring the name is honest; guessing it was not.

Red-proofed, each rc=1 against control rc=0: removing the 1.13.2 tmux guard,
adding an undeclared config dir, and renaming a declared installer.

Limit, printed in its own verdict: "guarded" is recognised by a `has <tool>`
test inside the named function or one call away; a guard written another way
would read as absent.
@YASoftwareDev
YASoftwareDev merged commit c86357f into master Sep 20, 2026
30 checks passed
@YASoftwareDev
YASoftwareDev deleted the test/config-needs-tool branch September 20, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants