913 lines down to 150. The ten functions were only 202 lines; the other 712 were a single top-level block, now eight phase functions across six libs. As in the previous split the bodies were wrapped WITHOUT re-indenting, because five heredocs use quoted terminators that must stay at column 0 (shfmt indented them afterwards, which is safe). The ~320-line custom-blocklist heredoc became custom_entries.hosts. It was 321 of the 370 lines of hosts_write.sh and cannot be split, so that lib could not otherwise fit the cap; a hosts-format data file is also far easier to audit and diff than a quoted heredoc. That move broke a guard, which is the important part of this commit: extract_custom_entries_from_script sliced the blocklist out of the script between "# Custom blocking entries" and the heredoc terminator. With the entries in a data file there is no terminator, so it would have extracted NOTHING -- and check_custom_entries_protection, the guard whose entire job is refusing to drop blocked domains, would have compared against an empty list and passed everything. It now reads the data file, and the extracted set is identical: 254 domains, diffed. A second, pre-existing bug surfaced while testing: extract_unblock_entries_from_script matched its OWN marker lines. PROTECTED_UNBLOCK_LIST_START and _END are word characters, so the '^# [a-zA-Z0-9._-]+$' pattern pulled both into the whitelist as if they were domains. Both are in this machine's live state file right now. Renaming either marker would have read as the whitelist growing and blocked the install outright. There is no dry-run or status mode, so this file cannot be proven by running it: an aborted run leaves /etc/hosts mutable with the guard's bind mount down. The proof is textual instead. Every one of the 8 wrapped phase bodies is byte-identical to its original line range; a line-multiset check found 0 lines lost; and an indentation-insensitive comparison against the pre-split file leaves exactly 8 absent lines, each an intentional edit (the rewritten extractor, three `readlink -f "$0"` made overridable, the /etc/hosts fallback made overridable, and the heredoc markers). /etc/hosts is byte-unchanged across the whole session, and `--help` output is identical. 36 assertions. Both anti-tamper guards at 100% line coverage (75/75 and 49/49), covering both directions of each: removing a blocked domain is refused and adding one allowed; growing the whitelist is refused and shrinking it allowed. A same-count swap is refused too, which a count-only check would have let through. The install phases themselves are deliberately untested -- running them would take down the protection they install. That is weaker evidence than the two previous splits had, and it is inherent to this file rather than a gap. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F3PzGc75gBcdxP3PkHXGcV |
||
|---|---|---|
| .github | ||
| .hippo | ||
| .vscode | ||
| billsplit | ||
| bucket_catch | ||
| docs | ||
| focus_owner | ||
| kcd2_dice_solver | ||
| linux_configuration | ||
| meta | ||
| phone_focus_mode | ||
| poker-stakes | ||
| python_pkg | ||
| reverse_survivors | ||
| third_party/agent-skills | ||
| .binary-allowlist | ||
| .copilotignore | ||
| .fvmrc | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .prettierignore | ||
| .shellcheckrc | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| DESIGN_AUDIT_TODO.md | ||
| lint_python.sh | ||
| NEXT_SESSION_PROMPT.md | ||
| pyproject.toml | ||
| README.md | ||
| refactor_claude_todo_resume.md | ||
| refactor_claude_todo.md | ||
| requirements.txt | ||
| run.sh | ||
testsAndMisc
A collection of personal projects, scripts, and experiments — from a GPS-based phone focus tool to Linux/Arch automation, with CI, linting, and pre-commit hooks across the board.
Highlights
Phone Focus Mode
Location-based app restriction for rooted Android. Automatically disables non-whitelisted apps within 500 m of home using ADB + Magisk. Features Haversine distance calculation, hysteresis to prevent toggling, fail-safe unlock, and state persistence. Bash, Android ADB.
Linux Configuration
Automated Arch Linux setup: fresh-install scripts, i3 window manager config, LaTeX environment, and system tests. Includes documentation and test result logging.
Scripts
Utility scripts for development workflows — build file validation, secret detection, and custom makepkg helpers.
Repository Layout
| Path | Description |
|---|---|
python_pkg/ |
Python packages (each maintained subpackage lives here) |
billsplit/ |
Receipt bill-splitting Flutter app — people, groups, per-item assignment, e-paragon import and xlsx export (Dart, 100 % line coverage gate) |
linux_configuration/ |
Arch Linux setup, i3 config, system maintenance scripts |
focus_owner/ |
Device Owner app enforcing focus mode on the unrooted Pixel 6a — geofence + night curfew, hides apps the phone cannot un-hide (Dart/Kotlin) |
phone_focus_mode/ |
GPS-based Android focus enforcer (rooted-era scripts; config.sh is still the policy source of truth for focus_owner/) |
reverse_survivors/ |
Reverse Survivors — React/Vite game where you play the horde against an AI survivor (TypeScript, 100 % coverage gate) |
scripts/ |
Workspace-level helper scripts and pre-commit hooks |
docs/ |
Reference docs and historical reports |
third_party/ |
Vendored upstream skills/agents |
meta/ |
Repo-wide tooling: pyproject.toml, requirements.txt, .pre-commit-config.yaml, run.sh, lint_python.sh, .fvmrc. Symlinked into the repo root so tools that auto-discover from root keep working. |
Archived / unmaintained projects live in the sibling repository
testsAndMisc-archive.
Tooling
- Python linting: Ruff with all rules enabled (see
meta/pyproject.toml) - Dependencies:
pip install -r meta/requirements.txt(combined runtime + dev) - CI: GitHub Actions — lint, build, and test on push
- Testing: pytest (Python), custom shell-based test harness for scripts