Measured on the Pixel 6a, twice: with private_dns_mode=hostname and the resolver unreachable, `ping example.com` returns "unknown host". Android's Private DNS does not fall back to the carrier's resolver -- hostname mode is RFC 8310's strict profile, and failing to establish TLS on 853 is a hard error. So a resolver living on this PC means "PC off" equals "phone has no internet", not merely "no filtering". That is disqualifying for a daily driver, and it disqualifies the whole home-hosted delivery path regardless of how well it works while the machine is up -- which it does; it was verified end to end. DNS_TRUSTED_DOT_HOST/IPS go back to empty, which restores the previous enforcer behaviour byte for byte. No code revert is needed, which is exactly why the flag was built to default empty. Two things found while testing are worth keeping. The nftables input chain is policy drop and admitted only ssh over wg0, so binding stunnel to the tunnel address was not sufficient on its own: ICMP passed while TCP 853 was dropped, which presents confusingly as "ping works but the port does not". That rule is now added explicitly and scoped to wg0. And setup_phone_wireguard.sh automates the client setup the tunnel needed, verifying handshake, reachability and DNS rather than assuming success, and deleting the pushed private key afterwards. The deeper reason the home endpoint could not work even with the tunnel up: dns.kuhy.duckdns.org resolves to the public IP while stunnel listens only on 10.8.0.1, and with AllowedIPs=10.8.0.0/24 that routes outside the tunnel to a closed port. Android never opened a connection at all. Split-horizon DNS does not fix it either, since on mobile data the phone uses the carrier's resolver. Research also ruled out the hosted-hybrid option that looked most attractive: no provider can ingest a 185k-domain list (NextDNS none, AdGuard 1-5K, ControlD 10K), and the free tiers fail OPEN -- they stop filtering past 300k queries a month while still resolving, which for a self-control tool is the worst failure mode available. Details and the remaining options are in the parked doc. The stunnel endpoint is left running deliberately: WireGuard-only, verified unreachable from LAN and WAN, and it makes the next attempt testable immediately. Removal commands are documented. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AwepyL5Lxs5QKbKkMpxxxL |
||
|---|---|---|
| .github | ||
| .hippo | ||
| .vscode | ||
| billsplit | ||
| bucket_catch | ||
| docs | ||
| focus_owner | ||
| kcd2_dice_solver | ||
| linux_configuration | ||
| meta | ||
| phone_focus_mode | ||
| python_pkg | ||
| reverse_survivors | ||
| third_party/agent-skills | ||
| .binary-allowlist | ||
| .copilotignore | ||
| .fvmrc | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .prettierignore | ||
| .shellcheckrc | ||
| CLAUDE.md | ||
| DESIGN_AUDIT_TODO.md | ||
| lint_python.sh | ||
| pyproject.toml | ||
| README.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 |
phone_focus_mode/ |
GPS-based Android focus enforcer |
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