testsAndMisc/DOCS-installer-fix.md
Krzysztof kuhy Rudnicki f15f00f3fe Re-point paths for the ~ reorganisation (home-tidy)
Also bumps the 16 meta/requirements pins the freshness gate flagged
(anthropic 1.5.0, numpy 2.5.3, pytest-randomly 5, flake8-bugbear 26.9.9,
ruff 0.16.7, pyright 1.1.414, selenium 4.49.0, hypothesis 6.168.0, lxml
6.1.3, pipdeptree 4.2.5, the two types-* stubs) and Flutter 3.47.3 in
meta/.fvmrc. One test still expected the pre-move ~/mcp-servers path.

The pre-commit hook fed .zsh files to shfmt and shellcheck, neither of
which parses zsh (SC2148/SC1071), so no zsh file could be committed since
the hook was tightened on 2026-08-22; those now get `zsh -n` instead. The
hook's own shfmt pass also staged its reformat of 8 shell files.

CI_GREEN_SKIP because main is red on exactly the dependency-freshness
finding this commit fixes, which is the documented use of that flag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
2026-09-11 20:50:19 +02:00

7.6 KiB

Next session: make install_core_system.sh actually work on a fresh machine

Paste everything below into a fresh Claude session (/clear first).


~/src/testsAndMisc/linux_configuration/install_core_system.sh is the documented way to set this machine up from scratch. It does not work. Three defects were found on 2026-08-22 by running the real installer in a disposable Arch VM (~/src/utils/vmbox) rather than by reading it — 2 of its 7 modules cannot install at all, and a third installs something that silently does nothing.

Do not trust this file's line numbers without re-checking them. They were correct on 2026-08-22; the repo moves.

The evidence

The sandbox progression, measured with the repo's own hardening checks:

State Result
Bare guest, nothing installed 0 passed / 17 skipped
After install_core_system.sh --all 10 passed / 14 skipped
After manually installing guard-lib + the shutdown timer 14 passed / 10 skipped
After manually running the hosts migration 18 passed, 6 skipped, 0 failed

The remaining 6 skips are legitimately screen_locker's. The gap between row 2 and row 4 is entirely defects 2 and 3 below: everything needed to reach a green machine already exists in the repos, but the documented install path never runs it.

Defect 1 — two module paths no longer exist

install_core_system.sh invokes:

  • line 129: bash "$REPO_ROOT/python_pkg/screen_locker/install_systemd.sh" — gone
  • line 143: sudo bash "$REPO_ROOT/python_pkg/steam_backlog_enforcer/install.sh" — gone

Both packages were extracted into their own repos. Verified on disk 2026-08-22:

  • ~/src/screen-locker/install_systemd.sh (5637 b, executable)
  • ~/src/steam-backlog-enforcer/install.sh (3248 b, executable)

"Workout screen locker" is a CORE module, so a fresh machine fails on the first thing the installer does.

Note this makes the installer cross-repo: ~/src/testsAndMisc no longer owns that code. That is design question (b) below — do not just hardcode ~/src/screen-locker and call it done without putting the question to kuhy.

Defect 2 — guard-lib is required but never installed

scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh depends on guardctl and dies with guardctl not found on PATH. Nothing in install_core_system.sh installs guard-lib, which lives at ~/src/utils/guard-lib/install.sh — a third sibling repo.

So the CORE module "Midnight shutdown timer" always fails on a fresh machine.

Defect 3 — the hosts file-guards are installed only by a one-shot script

install.sh in the extracted hosts-blocker repo (github.com/kuhyx/hosts-blocker, checked out at ~/src/hosts-blocker; it was scripts/periodic_background/hosts/install.sh when this was written) never installs the hosts/nsswitch/resolved file-guards. Its own comment block around line 109 claims otherwise:

Enforcement does not depend on these sources being immutable: /etc/hosts itself is chattr +i, guard-lib's "hosts" file-guard instance (guardctl file-guard status hosts) watches and re-enforces it against its canonical snapshot, and the same instance's bind mount pins it.

That is only true after running scripts/single_use/fixes/migrate_hosts_guard_to_guard_lib.sh (169 lines), which is filed under single_use/fixes/ and is not part of any install path.

A fresh machine following the documented path therefore gets chattr +i and no watcher, no canonical copy, no bind mount — immutability with nothing re-enforcing it. Verified both ways in the sandbox: 5 hardening checks stayed skipped until the migration was run, then passed.

Two design questions — ask kuhy, do not guess

Run these as a grilling round before writing any code.

(a) Where should defect 3's fix live? Either hosts/install.sh calls the migration script, or the migration's logic moves into install.sh and the one-shot script is deleted (or becomes a thin wrapper). The first is a smaller diff; the second stops single_use/fixes/ from being load-bearing, which is arguably what "single use" is supposed to mean.

(b) How should a testsAndMisc installer reach code in sibling repos? ~/src/screen-locker, ~/src/steam-backlog-enforcer and ~/src/utils/guard-lib are separate repos now. Options, none obviously right:

  1. Expect-adjacent — check for ~/src/screen-locker etc., fail with a clear message naming the repo to clone. Simple; the installer stops being self-contained.
  2. Clone if missing — the installer clones the siblings it needs. Works on a truly bare machine; puts network access and repo URLs into an installer that currently has neither.
  3. Drop those modules — install_core_system.sh installs only what testsAndMisc owns, and each sibling repo installs itself. Cleanest ownership; means there is no longer one command that sets up the machine.
  4. Invert entirely — a top-level bootstrap outside all four repos.

Do not assume ~/ layout is stable; whatever is chosen must fail loudly with an actionable message rather than silently skipping a module.

Done — checkable in a sandbox, not a sentence

The fix is done when, in a fresh vmbox guest:

vm share ~/src/testsAndMisc && vm share ~/src/utils
vm new inst
vm run inst 'git clone --no-hardlinks -q /mnt/hostrepo/testsAndMisc ~/tam'
# plus whatever cloning question (b)'s answer implies for the sibling repos
vm run inst 'cd ~/tam && echo y | bash linux_configuration/install_core_system.sh --all'
  1. Every module reports installed or explicitly skipped with a reason — zero entries in the installer's own Failed (...) summary section.
  2. The hardening checks reach 18 passed, 6 skipped, 0 failed, matching the row-4 measurement above, with no manual steps after the installer. The 6 skips must be the screen_locker ones; if a different 6 skip, that is a regression, not a pass.
  3. guardctl file-guard status hosts in the guest shows a live watcher with a canonical copy and a bind mount — not just chattr +i on /etc/hosts.
  4. Re-running the installer a second time is a no-op that still exits 0 (it must be idempotent; the sandbox makes this cheap to check).

How to work on this

  • Sandbox first, always. This is a root installer that writes /etc, systemd units, pacman hooks and chattr +i. Never run it on the host to test it. ~/src/utils/vmbox: vm new / vm run / vm reset. A sandbox pass does not prove the host is fine — report it that way.
  • Installers prompt; vm run closes stdin, so pipe echo y |.
  • vmbox is fast: vm run ~14s cold / ~3s warm, vm reset ~2s. Reuse one sandbox, do not rebuild per command.
  • ~/src/utils/vmbox/SESSION_RESULTS.md has the full 2026-08-22 measurements.
  • The 250-line file cap applies (~/src/utils/file_length). install.sh is at 130 lines and the migration at 169 — merging them wholesale will breach it, which is worth weighing in design question (a).
  • ~/src/testsAndMisc requires a docs/superpowers/evidence/*.json artifact for any code change (pre-commit gate ai-evidence-contract); copy docs/superpowers/evidence/template.json.

Out of scope

Do not fix boot-repair — its BIOS/GRUB guard landed 2026-08-22 in commit aec2b275. Do not refactor the installer's module-runner machinery (run_installer / ask_install); the defects are all in what it points at.