Commit Graph

5 Commits

Author SHA1 Message Date
1ea94e142c lan blocker: gateway mode, WARP drop with a Mon/Fri 09:00-15:30 window
Gateway mode routes LAN devices through the PC: forced DNS, DoH/DoT
dropped. The work laptop still bypassed it through Cloudflare WARP, so
the WARP ingress is dropped too. warp_window.sh opens it for the LAN
only Mon/Fri 09:00-15:30 (nft set with a timeout to 15:30), asked for
over a forced-command key by warp_home.sh, which keeps WARP off at home
otherwise because WARP fails closed. Also: dnsmasq upstreams, AAAA
filtering, DoH canary, and extracted_repo_dir resolving ~/src first
(the nightly blocklist refresh had failed since 2026-09-11).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019C8pdLR4MePsLocE1pWz7F
2026-10-25 09:52:40 +01:00
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
4c426eae0e Make install_core_system.sh work on a fresh machine
Some checks failed
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
Python tests / test (push) Has been cancelled
Two of the seven modules invoked python_pkg/ paths that stopped existing when
screen_locker and steam_backlog_enforcer were extracted into their own repos,
so the first thing the installer did on a fresh machine was fail. Nothing
installed guard-lib either, which meant the CORE "Midnight shutdown timer"
module always died with "guardctl not found on PATH".

Every module now resolves through install_module_from_repo, and
require_extracted_repo clones a missing sibling instead of only printing
instructions -- otherwise "clone it yourself" is not actionable on the bare
machine this script exists to set up. The clone drops privileges to the
invoking human via sudo -u, because an installer that re-execs under sudo
would otherwise leave a root-owned checkout in the user's home; a sandbox
cannot catch that, since the guest is root throughout. A clone that fails is
still a loud, fatal module failure, never a silent skip.

guard-lib is addressed as the "utils" repo: it is a subdirectory of
github.com/kuhyx/utils, so asking for "guard-lib" would resolve to
~/guard-lib and derive a clone URL that does not exist. It installs first,
before the modules that need guardctl.

Separately, the security hardening suite's screen_locker section hardcoded
$HOME/testsAndMisc/python_pkg/screen_locker/screen_lock.py. That path went
away with the extraction, so all five checks silently SKIPPED -- reporting a
clean run for tests that never executed, which is the exact failure mode
lib/extracted_repos.sh was written to prevent. It resolves the repo properly
now ($HOME is also wrong under sudo), and the assertions are rewritten against
the current implementation: the four symbols they grepped for no longer exist
anywhere, having been replaced by SPORT_CHOICES, SPORT_TABLE_TENNIS,
_validate_table_tennis and MANUAL_WORKOUT_REFLECTION_MIN_CHARS.

On this host that takes the suite from 18 passed / 1 failed / 5 skipped to
23 passed / 0 skipped. The task file's "18 passed / 6 skipped out of 17"
target was stale -- the suite is 24 checks now -- so it could not be matched
literally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-24 12:45:21 +02:00
309f4c8d42 Repair live self-repair broken by the flatten and extractions
Five live mechanisms were silently pointing at paths that no longer exist.
None of them announced it; each degraded to a log line or a missing file.

- hosts-file-monitor.service is ACTIVE and watches /etc/hosts for tampering,
  but its embedded installer path was the pre-flatten scripts/ one. It logged
  "Hosts install script not found" 37 times: it detected tampering it could
  not repair.
- dns-blocklist-refresh.service (enabled, next run 00:01) named a deleted
  single_use/features/ path, as did media-organizer.service under utils/.
- setup_periodic_system.sh read all TEN of its templates from
  periodic_background/system-maintenance/, which has held nothing but
  untracked .pyc and .coverage residue since system-maintenance was
  extracted. Every install of a service, timer or script was reading a file
  that was not there.
- /etc/sudoers.d/hosts-install-no-passwd granted NOPASSWD on the old hosts
  installer path.

Running the fixed dns unit then caught a bug the static checks missed: under
systemd there is no SUDO_USER and `id -un` is root, so the new resolver
returned /root/hosts-blocker and the service died with "Feed generator not
found". extracted_repo_home() now handles the bare-root case by falling back
to the owner of the lib file itself. Verified across all four invocation
modes: as the user, via sudo, as root with SUDO_USER unset, and with an
explicit *_DIR override.

The service now reports "Feed refreshed and dnsmasq reloaded (189038 lines)".
/etc/hosts is untouched throughout -- still 176888 lines, still chattr +i,
still bind-mounted by its guard.

Live artifacts were patched via validated temp files, never in-place: the
sudoers drop-in was checked with `visudo -cf` before install, and every
original is backed up under /var/tmp/*.pre-{extract,fix}.

Stale live references: 8 -> 2. The 2 that remain name digital_wellbeing
paths and can only be fixed when that unit is extracted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 20:39:59 +02:00
f72455662c Extract the hosts blocker into its own repo
linux_configuration/periodic_background/hosts/ is now
github.com/kuhyx/hosts-blocker, cloned at ~/hosts-blocker. Clears 5 of the 46
directory-depth violations; the remaining 41 are all digital_wellbeing, so
--warn stays on the depth hook until that unit moves too.

History was filtered across ALL FOUR paths the unit has lived at (hosts/,
linux_configuration/hosts/, linux_configuration/scripts/periodic_background/
hosts/, and the current one). Filtering on the current path alone would have
preserved 1 commit out of 51 -- the flatten moved it recently, so a naive
single --path silently truncates the history to the flatten commit and still
looks fine in `git log | head`.

No source line changed: all 15 files are byte-identical to the copies removed
here. install.sh already resolved its lib/ via BASH_SOURCE.

The six callers now resolve the checkout through a new shared helper,
linux_configuration/lib/extracted_repos.sh, which reads the invoking user's
home from SUDO_USER's passwd entry rather than $HOME -- several of these
scripts re-exec under sudo, where $HOME is /root. A missing checkout fails
loudly with a clone instruction; it is never a silent skip, which is the
failure mode that left screen-locker's self-repair dead for five months after
the 2026-05-15 reorg.

The live blocker is untouched: /etc/hosts keeps its chattr +i, and the guards
load their plugins from /usr/local/share/guard-lib-plugins/ (byte-identical by
md5), not from a repo path.

Verified: 25 tests pass from ~/hosts-blocker; shellcheck clean on the helper
and all six callers; sudo resolution prints /home/kuhy/hosts-blocker;
test_setup_dns_blocker.sh passes; report_live_state.sh --check is byte-identical
before and after, so no new stale references.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 20:30:18 +02:00