testsAndMisc/docs/superpowers/evidence/split-test-security-hardening-2026-08-16.json
Krzysztof kuhy Rudnicki 656375275b Split test_security_hardening.sh; finish the mutation-driver split
Two files under the cap.

test_security_hardening.sh (423) keeps its filename -- shell-tests.yml
runs the suite by name -- and its five sections move into three sourced
libs. They are top-level blocks, not functions, so each is wrapped and
called in the original order; the counters and LIVE_SECTION stay in the
entry, which sourcing shares. Verified by diffing a full run against the
same suite from a detached worktree at HEAD: byte-identical output, same
exit status, still 18/1/5 on this host. The one failure is pre-existing.

Linting a lib alone turns a bare LIVE_SECTION=1 into SC2034, since its
only reader is test_result in the entry. A live_section() setter makes
the write a real reference, so no suppression was needed.

The mutation-driver split was already in the tree from the previous
session and did not run: the operators had moved to
_session_autopsy_mutations.py but the driver still named Mutation
without importing it, so mypy and pylint both reported undefined-variable.
Restored the import; the script now reports all 12 tests killed.

block_compulsive_opening.sh (705) is deliberately untouched and now says
so in the contract. install_all copies the running script to
/usr/local/bin, so an entry sourcing lib/ would resolve SCRIPT_DIR there,
find nothing, and leave beeper, signal-desktop and discord unlaunchable
with a failing pacman hook. Splitting it means teaching the installer to
copy the libs -- a refactor, not a line-count split.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 22:24:02 +02:00

71 lines
4.5 KiB
JSON

{
"intent": "Bring linux_configuration/tests/test_security_hardening.sh under the 250-line cap without changing a single assertion or its result, and finish the meta/scripts/mutate_session_autopsy_hooks.py split that a previous session left half-applied and broken in the working tree.",
"scope": [
"linux_configuration/tests/test_security_hardening.sh (423 -> 116 lines)",
"linux_configuration/tests/lib/security_hosts_shutdown.sh (new)",
"linux_configuration/tests/lib/security_pacman.sh (new)",
"linux_configuration/tests/lib/security_apps.sh (new)",
"meta/scripts/mutate_session_autopsy_hooks.py (253 -> 175 lines)",
"meta/scripts/_session_autopsy_mutations.py (new, 99 lines)",
"Non-goal: changing, weakening, skipping or deleting any test",
"Non-goal: fixing the one pre-existing failure this suite reports on this host"
],
"changes": [
"Moved the five top-level test sections into three sourced libs, each section wrapped in a function and invoked from the entry script in the original order, so execution order is unchanged.",
"Kept the entry filename, since .github/workflows/shell-tests.yml runs this suite by filename.",
"Counters (PASS/FAIL/SKIP) and LIVE_SECTION still live in the entry script; sourcing shares the shell, so the libs mutate them exactly as the former top-level blocks did.",
"Added a live_section() setter in the entry script and routed the libs' LIVE_SECTION writes through it. Linted in isolation a bare assignment reads as SC2034, since its only reader (test_result) is in the entry file; the setter makes the write a real reference instead of a suppression.",
"Finished the mutate_session_autopsy_hooks.py split found half-applied in the working tree: the mutation operators had been moved to _session_autopsy_mutations.py but the driver still referenced Mutation without importing it, so mypy and pylint both failed with undefined-variable and the file could not have been committed as left."
],
"verification": [
{
"command": "bash -n on entry + all three libs",
"result": "pass",
"evidence": "OK test_security_hardening.sh; OK lib/security_apps.sh; OK lib/security_hosts_shutdown.sh; OK lib/security_pacman.sh"
},
{
"command": "shellcheck lib/security_*.sh (each lib alone, no -x)",
"result": "pass",
"evidence": "LIBS CLEAN - no SC2034, no suppressions added"
},
{
"command": "shellcheck -x test_security_hardening.sh",
"result": "pass",
"evidence": "ENTRY CLEAN"
},
{
"command": "shfmt -d test_security_hardening.sh lib/security_*.sh",
"result": "pass",
"evidence": "SHFMT CLEAN. The pre-split entry was already shfmt-dirty; the new files are clean and were not made dirty."
},
{
"command": "bash test_security_hardening.sh, diffed against the same suite run from a detached worktree at HEAD",
"result": "pass",
"evidence": "OUTPUT BYTE-IDENTICAL PRE/POST SPLIT after normalising the repo path prefix. Both runs: Passed 18 / Failed 1 / Skipped 5, both exit 1. The single failure is pre-existing and unrelated to this split."
},
{
"command": "python3 meta/scripts/mutate_session_autopsy_hooks.py",
"result": "pass",
"evidence": "PASS: all 12 tests killed by at least one mutation. Ran end to end, so the bare 'from _session_autopsy_mutations import ...' resolves in the real invocation path."
},
{
"command": "pre-commit run --files on both Python files",
"result": "pass",
"evidence": "ruff, ruff format, mypy, pylint, bandit and pytest-with-coverage all Passed after the missing Mutation import was restored; the mutation hook itself reports PASS."
},
{
"command": "bash ~/utils/scripts/check_file_length.sh --all | grep -c 'over by'",
"result": "pass",
"evidence": "66 -> 62 violations; neither split file appears any more."
}
],
"risks": [
"The libs are only valid when sourced from the entry script, which owns the counters, colors and test_result(). Running a lib directly is not supported and never was a use case.",
"A future section added to a lib must call live_section() rather than assigning LIVE_SECTION, or it reintroduces SC2034."
],
"rollback": [
"git revert the commit; the entry script returns to a single 423-line file and the lib/ directory disappears.",
"After rollback, run bash linux_configuration/tests/test_security_hardening.sh and confirm it still reports Passed 18 / Failed 1 / Skipped 5 on this host."
]
}