Commit Graph

9 Commits

Author SHA1 Message Date
7e2d78c7db Add the G29 shifter HID-BPF fix (1st/3rd engage reliably)
Live on this host since 2026-09-11 but never committed. The wheel firmware
decodes the shifter's hall sensor itself and this unit's top row rests at
Y 180-193, below the ~195 engage threshold, so 1st/3rd often did not
register. g29_shifter.bpf.c re-decodes those two gates from the raw X/Y
bytes with hysteresis (engage >= 160, release <= 140) and ORs the bit in
before hid-logitech parses the report; it never clears a bit, so the
firmware's working gates cannot regress. fix_g29_shifter.sh builds,
attaches and installs it persistently (udev-hid-bpf rule + a systemd
safety-net unit pulled in on every re-enumeration); g29_shifter_capture.py
records and grades raw captures per gate.

Two files were over the 250-line cap: the test file is split at the
record/CLI boundary with the report builders moved into a conftest fixture
(the naming hook allows only test_*.py in tests/), and the grader's
docstrings are tightened. No behaviour change to the installed fix.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SS8M5wk88nJTXxDWz61KKk
2026-09-14 22:12:31 +02: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
08aac8d7d1 Flatten i3-configuration and misc/testsAndMisc-bash
i3 config was filed under periodic_background, which it never was. It is
now linux_configuration/i3/ (config + installer) and
linux_configuration/i3blocks/ (the status scripts), both at depth 2.

misc/testsAndMisc-bash/ was a directory named after the repo it already
lived in, so its contents moved up to misc/. Its stray .gitignore came
along, keeping the media rules working from the new location; its
.vscode/tasks.json did not, because it invoked Bash/transcribe.sh, a path
this repo dropped long ago.

Most of this commit is the references the previous flatten missed. Its
regex skipped anything with a variable prefix, which left 16 files --
including check_and_enable_services.sh and install_core_system.sh, the
orchestrators -- still naming $CONFIG_DIR/scripts/periodic_background/...
It had also rewritten three i3 paths into scripts/i3blocks/, a directory
that has never existed; the i3blocks suites caught that by failing.

13 more symlinks broke on the i3 move. Repointed, and cpu_monitor/volume/
disk were run again to confirm the bar still reports.

Depth 139 -> 104. Roughly 47 of the remainder sit in digital_wellbeing
and hosts, still deferred. The rest encode real structure -- a C project,
Python package directories, artgate's routes/styles, systemd unit dirs --
so flattening them further would destroy information rather than
taxonomy.

Verified: 1798 tests at 100%, both i3blocks suites pass, the shell
coverage gate is clean, and the relocated media rules still ignore what
they should while test_fw.srt stays tracked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 19:02:18 +02:00
4f2b0ccdf7 Dissolve linux_configuration/scripts/ and single_use/
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.

Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.

The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:

  - 52 relative `source` lines for lib/common.sh and lib/android.sh. The
    correct prefix differs per file: 40 were ../../ and 12 were ../../../,
    so a blanket replace would have fixed one set and broken the other.
  - REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
    each walking up four levels from a directory now two levels shallower.
    This caused a real regression -- the fixes suite went red with
    "log_warn: command not found" -- caught by running it and comparing
    against the pre-move baseline worktree.
  - conftest.py's sys.path entries, which took the pytest gate down with
    14 collection errors, and the `# shellcheck source=` directives, which
    took shellcheck down with SC1091.

16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.

Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 18:53:30 +02:00
a5209b6878 Extract phone_focus_mode together with focus_policy
github.com/kuhyx/phone-focus-mode

The two halves go as one repo: focus_policy parses phone_focus_mode's
config.sh into the typed policy that focus-owner consumes, and nothing
else references it. 77 commits of history, plus the two Python suites
from linux_configuration/tests/ and the six mutation fixtures from
meta/scripts/fixtures/, all of which named phone_focus_mode paths.

Running the suites -- not reading them -- turned up a real defect the
extraction would otherwise have inherited. config.sh sources the
untracked config_secrets.sh, and ctl_libs_harness.sh never pinned
HOME_LAT/HOME_LON, so the distance assertions were checking against
whatever real coordinates that file happened to hold. The suite passed on
this machine and could not run anywhere else, and a real home location
was load-bearing in a pass/fail condition. The harness now pins a pair
4300 m south of the coordinate its own case seeds, and config.sh sources
the secrets file only when it exists. 136/136 pass with no secrets file
present.

Before making the repo public I scanned the whole history for the known
home coordinates and for any committed config_secrets.sh: zero hits, and
the file was never tracked. The new repo also gained a .gitignore, since
none came across in the filter-repo pass.

test_magisk_service.sh hangs. It hangs identically in the pre-extraction
baseline worktree and appears in no CI list here, so the new repo's CI
skips it with that reason rather than pretending it passes.

check_python_location.sh loses its phone_focus_mode exception now that
the directory is gone; every tracked .py still passes it. The .gitignore
rules for config_secrets.sh and the keystore STAY -- the working copy is
still on this machine and still holds a real location.

Depth 262 -> 248.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 18:32:58 +02:00
a1f8044a4a Extract system-maintenance, the isolated subsystem
github.com/kuhyx/system-maintenance, cloned to ~/system-maintenance

First of the four live subsystems, and the one with no cross-unit source
edges, so it establishes the pattern for the harder three. Passed in
vmbox first -- the installer ran from an extracted-layout copy in the
guest and detected its distro without any monorepo path -- then on the
host.

Its 21 Python and shell test files lived in linux_configuration/tests/,
reaching bin/ through a shared conftest. Twenty moved with the code and
got their own conftest; the shared one stays, since it serves several
script directories that are not going anywhere.

test_shutdown_timer_monitor.sh stays here. It is a pair test: it checks
that digital_wellbeing's installer template and the monitor it installs
still agree, so it belongs to whichever half owns the installer. It now
reads the monitor from ~/system-maintenance and SKIPs when that checkout
is absent.

An intermediate version of that test fell back to /usr/local/bin, which
HUNG -- the installed copy is stale and differs from source, so the test
was comparing an installer template against a binary it never generated.
Falling back to it would have been worse than skipping, so the fallback
is gone and the comment says why.

Also removed test_hosts_file_monitor.sh from shell-tests.yml's explicit
list: it left with the subsystem, and CI would have failed on the missing
file rather than quietly skipping it.

Verified: 136 tests pass in the new repo, 202 still pass here, the pair
test passes against the checkout and skips without it, and both the shell
coverage gate and shellcheck are clean. Depth 294 -> 267.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
2026-08-23 17:55:29 +02:00
7587cd9604 transcribe_helpers: cover 0% -> 100% before splitting
transcribe_helpers.py is 289 lines against the 250-line cap and was
completely untested. Tests land first, in their own commit, so the split
that follows is verified against tests that predate the seam.

Left at its current path rather than moved under python_pkg/: transcribe.sh
invokes it by path inside a dedicated ML venv, and transcribe_fw.py imports
two siblings by bare name, so the closure is five files (1236 lines), not
three. Tests go in linux_configuration/tests/ instead, whose conftest
already puts standalone script directories on sys.path - the same
arrangement the usage_report work used, and still collected by CI.

The ML dependencies are never installed in CI and the module reaches them
only through _try_import, so patching that one seam covers every probe in
both directions. An AST scan at every nesting level confirmed there is no
other path to them: the only direct numpy imports sit under TYPE_CHECKING.

41 tests, 100% line and branch. The last gap was the dispatch guard at
line 284, unreachable through the CLI because argparse's choices list and
the dispatch dict carry the same eight commands; covering it by admitting a
ninth choice also documents why the guard is there.

Split across four test files because a single module hit 291 lines - over
the cap this work exists to clear.

Verified: python-version prints 3.14, check-faster-whisper exits 7 with no
ML deps present, generate-wav writes a 96044-byte WAV; 243 tests pass in the
directory, up from 202 by exactly the 41 added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
2026-08-17 13:29:07 +02:00
2e1e370c0f refactor: extract all inline Python from shell scripts into proper .py files
Move every multi-line python heredoc/`-c` block into a dedicated .py file so
ruff, mypy, pylint, bandit, and pytest can apply to it:
- linux_configuration/zsh/calc-live.zsh → python_pkg/live_calc/calc_eval.py (100% branch cov, 46 tests)
- meta/scripts/check_ai_evidence.sh → meta/scripts/validate_evidence.py
- meta/scripts/check_agent_contract.sh → meta/scripts/validate_contract.py
- phone_focus_mode/lib/monitor.sh → phone_focus_mode/lib/monitor_report.py
- phone_focus_mode/deploy.sh → phone_focus_mode/strip_workout_hosts.py
- linux_configuration/.../analyze_repo.sh → fast_count.py

Also: add zsh-syntax pre-commit hook (zsh -n); exclude zsh from shellcheck;
add tests for all 4 non-python_pkg helpers; update CLAUDE.md Shell Style with
the no-inline-Python rule.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 10:31:48 +02:00
20d5d1f89b fix(usage_report): stop charging atop's HZ field as CPU; bundle since-last-report mode
atop's `-P PRC` output inserts the clock-tick rate (HZ=100) between the
`state` and `utime` columns. Both the Python parser and the native C
aggregator read that constant as utime for every record, charging a flat
1 CPU-second per record — so cpu_seconds collapsed to pid_count and
short-lived fork-storm commands (xset, dd, chronyc) topped the CPU table
(xset showed 67h). The old test fixtures lacked the HZ field, so code and
tests agreed on the bug.

- _parse_prc / atop_agg.c: read utime/stime past the HZ field (after+2/+3,
  tokens[10]/[11]); bump the length guards accordingly
- restore C/atop_agg (deleted in 89b4f59) under linux_configuration/C/,
  where the build path resolves; corrected test fixtures to include HZ
- _atop_agg_binary: fall back to the Python parser when the C source tree
  is gone instead of trusting an orphaned cached binary
- add regression tests proving HZ is not summed as CPU
- bundle the in-progress since-last-report multi-day aggregation (segments,
  -b/-e bounding, persisted state, window merging) and its tests/conftest
- meta: gate linux_configuration/tests in pytest_changed_packages.py

Verified by running usage_report.py --date 20260604: Top CPU now led by
SkyrimSE; xset/dd/chronyc fall to ~0. C unit tests + full pytest suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 18:13:47 +02:00