Docker mysql:8.0.33 container, judge-style output grading, 12 original drills with live-verified references kept in tests only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWZewj4WS5X6AZyjWDp
A red baseline blocked even the pin bump that fixes it. Changes touching only .fvmrc, pubspec, package.json, lockfiles, requirements*.txt or pyproject.toml now pass, with a loud line; all else stays fail-closed. Bats tests added.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYdwRAtMg7ki6TKxuU
Released right after the previous pin bump landed; the dependency-freshness
CI job flagged it as the only finding.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBScELfMUiieK9ManFbS3Y
Upstream releases since 10-19 left 8 pins in meta/requirements*.txt behind,
turning the dependency-freshness and pre-commit CI jobs red. code_tutor (the
only anthropic importer) passes its 16 tests on 2.1.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBScELfMUiieK9ManFbS3Y
Fixes the red Pre-commit CI on main: dependency-freshness flagged
anthropic, hypothesis, pipdeptree, pre-commit, reorder-python-imports,
ruff and pillow. artgate + random_jpg (the PIL users) pass on pillow 13.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Lhzv7c391mTKWfwU17V7Z
i3blocks' environment has no ~/.local/bin, so `command -v daily-limits`
failed and every left-click on ⏻/🎮 was silently dropped. Call the launcher
by path (DAILY_LIMITS_BIN), detach with setsid, and notify when it is
missing. Also bumps the two pins behind latest stable that turned the
freshness gate red on 433cec27.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QrjUTo1yhgAsUUasdw4bpG
[book_guard] shows this month's paper-book pace from the state.json
book-guard publishes (green on pace, yellow behind but unlocked, red when
locked or the timer is disarmed, orange when missing/stale); a click opens
book-guard-desktop -- the same way [screen_locker] opens its UI. Behaviour
test in tests/test_i3blocks_book_guard.sh.
meta/requirements.txt: gatelock 0.9.0 (the shared morning-session reader),
plus today's newest stable for anthropic, cryptography, flake8-bugbear,
geopandas, howlongtobeatpy, pyflakes, selenium, mypy, pylint and ruff.
Prunes the oldest evidence artifact to stay at the 60-file cap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBbkN4ZB4aUPJPzR2prRan
The package now lives in its own private repo at ~/src/wsg-grabber, with
the 14 commits that touched it. /usr/local/bin/wsg-grabber was regenerated
by that repo's install.sh, so nothing here runs it any more.
hypothesis 6.168.2 -> 6.168.3: an upstream release turned the Pre-commit
checks and dependency freshness jobs red on 33f0fee3.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8G3BNETGmbr6aM5cc18g4
The dependency-freshness gate went red on hypothesis 6.168.2, released
2026-09-27. Newest stable, exact pin, nothing else changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KFwA9nymhUdTrVF65kigTV
`secret-tool lookup` is non-interactive — on a locked keyring it returns
nothing and shows no dialog — and a busctl Unlock+Prompt pair cannot work
either, because Secret Service prompt objects die with the D-Bus
connection that created them. secretstorage keeps one connection:
get_default_collection().unlock() pops the gcr dialog and blocks until it
is answered. Verified on the real profile: 5 v11 rows -> v10, then with
the keyring re-locked Helium (through the wrapper, so the flags file and
LeechBlock apply) lists all 5 logins and keeps every row.
`pgrep -f /opt/helium-browser-bin` also matched the invoking shell when
its argv mentioned the path, so the guard refused on an idle machine;
now anchored to `^/opt/helium-browser-bin/`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8YGXVZdNUG79q5DGsdMm3
Chromium 151 removed the last Manifest V2 code paths and the Web Store
purged uBlock Origin on 2026-08-31, so ungoogled-chromium 153 cannot load
the full blocker any more. Helium (GPL-3, ungoogled-chromium base) bundles
uBO 1.75.0 as a component extension and keeps MV2 alive.
- installers/install_helium.sh: pacman deps, AUR via yay or makepkg
(+validpgpkeys import), /usr/local/bin/helium-browser ->
browser-preexec-wrapper so LeechBlock NG and the hosts refresh still
apply, --clone-profile with a downgrade check and running-browser
refusal, then the verifier. Passed in vmbox from scratch, then host.
- installers/verify_helium.py: Xvfb + DevTools exit-code gate — uBO
background_page + manifest_version 2, every /etc/chromium/policies key
on chrome://policy (Helium reads that dir natively), adblock-tester >= 95.
- installers/migrate_helium_passwords_to_basic.py: lightdm autologin
leaves gnome-keyring locked, so the 5 v11 logins make Helium prompt on
every launch; this re-encrypts them as v10 and only then enables
--password-store=basic.
- register helium-browser in aur_packages.txt and the periodic browser
wrapper/service lists; pylint hook gets websockets + cryptography;
codespell learns the vendor name; anthropic 1.6.0 -> 1.7.0 (gate red);
oldest evidence artifact pruned to stay under the 60-file cap.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8YGXVZdNUG79q5DGsdMm3
Both moved between the local gate run and CI; CI_GREEN_SKIP=1 because
this commit is the fix.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mLnUeoJ3mUwGRTowTUH6d
CI has been red since db243fe on exactly these two pins (the freshness
gate; nothing else in that run failed). Nothing in the monorepo imports
gatelock; it is a listed requirement only. Committed with CI_GREEN_SKIP=1
because this commit is the fix the ci-baseline-green hook asks for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mLnUeoJ3mUwGRTowTUH6d
A push took ~13s. prettier is a pre-push hook precisely because Node's
startup dominates its runtime, and pre-commit chunks a large file list into
several invocations -- a 106-file push paid ten cold Node starts. ci-mirror,
the hook that looks expensive, was already 0.02s once its green-tree cache
hit.
A file whose content, prettier version and prettier config are all unchanged
since its last clean check cannot have become unformatted, so the verdict is
now cached and the file never reaches Node. Only clean verdicts are recorded,
so a formatting regression is always re-checked; the key includes
`prettier --version` and every config file, so an upgrade or a config edit
invalidates the cache wholesale. The systemd-run memory cap is unchanged.
Measured on the same push range: 13.0s -> 3.3s total, of which ~0.6s is
hooks and the rest is git's own network negotiation. On a 40-file list the
runner itself goes 0.652s -> 0.057s, starting no prettier process at all.
endurain/README.md and copilot-instructions.md are reflowed: the ~
reorganisation lengthened paths inside them, which changed prettier's
markdown table alignment.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
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
`verify` gated on the two invariants whose breach cut every bridged
container off the internet on 2026-08-29 and again after the 2026-08-30
reboot -- but nothing invoked it, so it reported drift only when a human
thought to ask, and the outage it exists for is exactly the one nobody
thinks to ask about.
nftables-drift.service now runs it after nftables.service, docker.service
and network-online.target at every boot, plus a daily Persistent timer. A
breach is a failed unit in `systemctl --failed`, not a log line: a
self-check that detects a failure has to gate, not warn.
Proven in ~/utils/vmbox across two real reboots -- drifted /etc leaves the
unit failed with the diff and the missing docker0 accept in its journal,
matching /etc leaves it active with no false positive -- then installed and
run green on the host. Not yet observed across a host reboot.
Also bumps the gatelock pin to v0.7.3, which is what turned main's
dependency-freshness job red; CI_GREEN_SKIP is set because this commit is
that fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015d48t4qsQLBJnDwDeo2Nom
wake_alarm._alarm no longer exists: the PC's waking role was deleted in
kuhyx/wake-alarm, and the phone owns the alarm now. This removes ALARM_MODULE,
_run_alarm() and the --with-alarm flag, leaving one leg -- the workout lock.
Landing this in the same change as the deletion is the point. An orchestrator
left pointing at a module that no longer exists is exactly the failure this
repo has already had once: after screen-locker was extracted on 2026-05-28 the
reference here went stale and the workout lock died with ModuleNotFoundError on
every run for a month, while the alarm half kept working and hid it.
morning-routine.service loses --with-alarm and its comments now name what
actually starts it: wake-alarm-trigger.timer, at the phone's synced alarm time,
not the deleted systemd-sleep hook. Environment=DISPLAY=:0 stays -- the comment
credited it to the alarm's Tk window, but workout-locker.service needs it too.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PcdngP688mW6rJye3LRkSN
Upstream released it between two CI runs today, which is enough to turn the
freshness gate red on a commit that touched no Python -- the documented and
expected behaviour of a gate that checks "newest stable" rather than "newest
stable as of whenever someone last looked".
The pre-commit pylint hook takes its version from the mirror rev, not from
this file, so nothing about which checks run changes here.
Also refreshes the isort note: 4.0.7 declared `isort<9`, 4.0.8 declares
`isort!=5.13,<10,>=5`, so the comment's specific bound was already stale.
Reworded to state the constraint's purpose rather than a version that moves.
Fixes the red main that ci-baseline-green is blocking commits on.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7BaCSV8FEtcNgVDVsRAJj
The guard prints `CI_GREEN_SKIP=1 git commit ...` and stops there, but it runs
at two stages: at commit, and again inside the pre-push CI mirror's
clean-worktree `pre-commit` run, which sees the same still-red baseline. So the
documented escape gets you past the commit and into an identical wall at push,
with no hint and nothing in the output connecting the two.
Hit today landing the pre-commit cache-key fix: the commit went through, the
push did not. The variable is read from the environment and `ci_mirror.sh` does
not scrub it, so `CI_GREEN_SKIP=1 git push` carries through to the nested run --
which is now what the message says.
Verified both paths: with the variable set the script warns and exits 0, and
against today's green main it exits 0 silently. shellcheck clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfnJmxxsZ534AKk16rC2Gr
Already red before today's Python work touched the repo; the commit hook had no
reason to look at the requirements files, so only a whole-tree run saw it.
Bumped across every repo pinning 7.15.4 in the same pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfnJmxxsZ534AKk16rC2Gr
`requires-python` and the CI pin already said 3.14, but ruff, mypy and pylint
were still grading `meta/` against 3.10 -- three tools judging an interpreter
nothing runs any more, and ruff withholding the pyupgrade fixes that only
become safe at the newer target. `pin_ci_python.py` rewrites these three knobs.
What the stale target was hiding: `datetime.timezone.utc` where `datetime.UTC`
is now correct (UP017), and ruff's stable formatter applying PEP 758 --
`except (A, B):` becomes `except A, B:`. That makes the source 3.14-only at the
syntax level, which is what `requires-python = ">=3.14"` already promised; kuhy
chose it deliberately over holding ruff a release back (2026-08-29).
Also drops a comment in `wsg_grabber/models.py` that the bump makes false: it
explained why the file used ``str, Enum`` instead of ``StrEnum`` under mypy at
3.10, sitting directly above a ``class Verdict(StrEnum)`` that had already
stopped obeying it.
ruff, ruff-format, mypy --strict and pylint all clean at the new target.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfnJmxxsZ534AKk16rC2Gr
`{"flutter": "stable"}` names a moving target: two machines on the same commit
can build with different SDKs, and a freshness check has nothing to compare it
against. This is the only .fvmrc in the fleet, and it was the one file the new
dependency-freshness gate could not evaluate.
Purely declarative today -- nothing in any repo invokes `fvm flutter`, and fvm
has no SDKs cached, so the build path is unchanged and still resolves the
pacman-installed SDK through ~/.local/bin/flutter.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CRykabMwPgDzFHcARoqpaK
The last unit over the cap is now github.com/kuhyx/digital-wellbeing, cloned
at ~/digital-wellbeing, and `--warn` is gone from the directory-depth-cap
hook. `check_directory_depth.sh --all` exits 0 with zero violations, down from
46 at the start of the session. That was the point of the campaign.
History was filtered across all three paths the unit has lived at (63
commits); the current path alone holds 2.
The six suites that test this code lived in linux_configuration/tests/ rather
than beside it, so they were filtered separately (24 commits) and merged in as
a second root. A path filter of the unit alone would have left them here,
testing code that had left the repo -- and their names would still have been
in shell-tests.yml's hardcoded arrays, failing CI on missing files.
linux_configuration/lib/common.sh is vendored into vendor/ rather than trimmed
to the four functions actually used: set_actual_user_vars calls two of the
others, so a trim breaks silently. It is in vendor/ and not lib/ because
test_music_parallelism.sh copies the unit's own lib/ into a scratch worktree
while stubbing the shared lib; in one directory the real common.sh overwrote
the stub, and the suite silently measured the wrong library.
Running the callers caught what shellcheck and grep both missed:
check_and_enable_services.sh died with "DW_REPO: unbound variable" because the
definition sat below its first use. It now runs clean and reports ok for every
extracted-unit check.
Two long-standing live defects fixed as a consequence. The pacman-wrapper
drift manifest embeds ABSOLUTE paths and had named deleted scripts/ paths
since the flatten, so the check reported a permanent false "stale or
tampered"; it now verifies, with unchanged hashes proving the extracted bytes
are identical. And the last two stale live references are gone: 8 -> 0.
The two pre-commit excludes for setup_midnight_shutdown.sh are dropped rather
than moved. lsattr shows nothing in the unit is chattr +i any more, and the
fixer hooks leave the file alone when allowed to run.
Removing 80 shell files also shrank the jscpd denominator enough that the
virtualenv/tqdm clones inside the GENERATED .ci-mirror-venv/ tipped the repo
to 2.09% and blocked this commit, which adds no duplication. That directory is
the same vendored third-party shell the ignore list already excludes as
.venv/, just under another name; jscpd walks the working tree rather than the
index, so being untracked did not spare it. Excluded by name: 1.74%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
The push kept failing with "1798 passed" immediately followed by "Killed".
The suite was never the problem: it peaks at ~0.29 GiB against its own 2G
cap. ci_mirror.sh runs pre-commit --all-files and the pytest gate
concurrently, and the pre-commit tree peaks at ~1.75 GiB (mypy and pylint
repo-wide, invisible to /usr/bin/time because it measures only the parent).
The pair wants ~2 GiB at once; the pytest scope has MemorySwapMax=0, so on
a loaded machine it is the one that dies.
Concurrency is now conditional on MemAvailable. Above 4 GiB the fast path
is unchanged. The probe lives in ci_mirror_mem.sh, following the existing
ci_mirror_range/ci_mirror_shell split, which also keeps ci_mirror.sh under
the line cap.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
A gate that blocks a commit with no tooling to clear it just moves the
problem to whoever hits it. --prune stages the removal of the oldest
artifacts, keeping the newest 20 per directory plus the template, and
leaves the commit to the operator.
Running it caught a bug that reading it would not: sorting on %cs (date
only) ties every artifact committed the same day, so sort fell back to the
path and the prune deleted alphabetically - it picked one of today's
newest files instead of the oldest. Sorts on %ct with -rn now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp