testsAndMisc/docs/superpowers/contracts/trace-prefix-writes-2026-08-16.json
Krzysztof kuhy Rudnicki f6356d4725
Some checks are pending
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Trace scripts that place files, via a prefix redirect
Shell redirections are builtins, so no PATH stub can intercept
`cat > /etc/modprobe.d/x.conf`. That left installer scripts unverifiable:
stub cp/chmod/ln and the trace is nearly empty, don't and the run rewrites
the live system.

--prefix redirects HOME and every XDG_* base into a temp tree. XDG_DATA_HOME
is exported explicitly, not left to default off HOME: install_leechblock.sh
reads it directly and then runs `rsync -a --delete` at it.

--bind-abs binds hardcoded absolutes via bwrap --unshare-user --uid 0, leaf
directories only. uid 0 is load-bearing beyond permissions: common.sh's
require_root does `exec sudo "$0"`, and under the sudo stub that truncated
the whole run to one recorded call -- a trace that diffs clean against any
split. Binding /etc wholesale was measured to shadow /etc/passwd, collapse
$SUDO_USER to /home//, and mask a nested bind, so the scanner never emits it.

The trace gains a manifest of every file written, with content hashes. That
section is the point: with it, a dropped write in the fixture pair is a
one-line diff; with it stripped, the two traces are identical, i.e. the old
harness passed that broken split. Hashes normalize the prefix to @PREFIX@
because install_usage_monitoring.sh writes an unquoted heredoc that bakes
$HOME into the artifact.

Verified: ~/.config/systemd/user, ~/.local/bin, ~/.local/share and
/etc/modprobe.d byte-identical before and after; usage-report units still 2.
The three prior regressions are now committed fixtures rather than ad-hoc --
one was silently neutered mid-change when a trailing echo added for SC2034
became the function's last statement and turned exit 1 into exit 0.

Stub generation moved to lib/ because --prefix pushed the harness to 252
lines, over the cap it exists to serve.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-16 23:31:49 +02:00

23 lines
3.3 KiB
JSON

{
"title": "Make write-to-system installers traceable with a prefix redirect",
"objective": "Extend meta/scripts/trace_shell_split.sh so scripts whose job is placing files can be executed safely and diffed. Shell redirections are builtins and cannot be intercepted by PATH stubs, so this class of script was previously unverifiable: stubbing cp/chmod/ln yields a near-empty trace, and not stubbing them rewrites the live system. This is the harness change that unblocks those splits; it is explicitly not a split.",
"acceptance_criteria": [
"trace_shell_split.sh can execute install_usage_monitoring.sh and nvidia_troubleshoot.sh and produce a diffable trace with the same format as before: exit status, ordered stubbed calls with arguments, stdout, stderr.",
"The trace SHOWS each redirected write with its destination and a content hash, so a dropped write is visible; a redirect that hid its writes would recreate the silent-stub trap it is meant to avoid.",
"The real ~/.config/systemd/user/, ~/.local/bin/ and /etc/modprobe.d/ are provably untouched after those runs, compared against snapshots taken before the first run.",
"A fixture pair proves the trace diff DETECTS a dropped write, and that the same diff without the manifest section is identical - i.e. that the harness catches a real break rather than merely running.",
"The three existing regression fixtures (set -e function-tail abort, self-referencing nameref, valued-stub branch) still behave as documented; they are committed as runnable files rather than left ad-hoc.",
"Traces captured WITHOUT the new flag remain byte-identical to previously captured ones, so the change does not invalidate existing baselines.",
"shellcheck and shfmt -d clean on every changed shell file, with findings fixed rather than suppressed.",
"Every changed file stays under the 250-line cap, including trace_shell_split.sh itself - the harness is not exempt from the rule it serves."
],
"out_of_scope": [
"Splitting any script. No target is split this session; the harness lands first and is proven first.",
"block_compulsive_opening.sh, whose install_all copies the running script into /usr/local/bin and which the handoff records as breaking three daily-use apps plus the pacman rewrap hook if split badly.",
"Making the sudo stub execute its argument. That would change every existing trace and turn sudo from a safety barrier into a passthrough; it is recorded as a named limitation instead.",
"Wiring the file-length pre-commit hook, which must land last, only once check_file_length.sh --all exits 0.",
"Weakening the gate in any way: no suppressions, no exclude entries."
],
"verifier": "meta/scripts/trace_shell_split.sh install_usage_monitoring.sh --prefix <d> (manifest lists all 5 artifacts), then diff of before/after snapshots of ~/.config/systemd/user, ~/.local/bin, ~/.local/share, /etc/modprobe.d plus systemctl --user list-unit-files | grep -c usage-report; diff of traces of fixtures/dropped_write_before.sh and dropped_write_after.sh (must differ by exactly the missing .timer line, and must be identical once the manifest section is stripped); the three regression fixtures re-run and checked against their documented exit statuses; shellcheck and shfmt -d on all changed shell files; wc -l under 250 for each."
}