Skip to content

Latest commit

 

History

History
116 lines (71 loc) · 5.04 KB

File metadata and controls

116 lines (71 loc) · 5.04 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this project is

Idempotent macOS script that creates /etc/resolver/ overrides for archive.today and its mirror domains, routing them through a trusted DNS nameserver (Google DNS 8.8.8.8) to bypass Cloudflare 1.1.1.1 blocks. Single-file Bash project — install.sh is the entire codebase.

Commands

# Lint (matches CI)
shellcheck --severity=warning install.sh

# Syntax check
bash -n install.sh

# Dry-run (requires macOS; no root needed)
sudo ./install.sh --dry-run --no-fetch

# Update mirrors from Wikipedia (no root)
./install.sh --update-mirrors --dry-run

# Install resolver files
sudo ./install.sh

# Uninstall
sudo ./install.sh --uninstall

Architecture

Single script (install.sh) with two modes:

  • --update-mirrors: Fetches Wikipedia API, extracts <li>archive.TLD</li> from the infobox, rewrites mirrors.txt. No root needed.
  • Default (install): Reads mirrors.txt (fetched from GitHub, or local with --no-fetch), writes /etc/resolver/archive.today with the nameserver, symlinks all other mirrors to that file, removes stale entries via manifest at /etc/resolver/.archive-resolver.

Key design: Mirror symlinks point to the filename archive.today (relative, not absolute path) so changing the nameserver only requires updating one file.

mirrors.txt is auto-updated by CI, not a static canonical list. The update-mirrors.yml workflow runs monthly, compares sorted sets (order-insensitive), and opens a PR if domains changed.

Release process

  1. Bump SCRIPT_VERSION in install.sh
  2. Push on a release branch, merge to main
  3. Tag vMAJOR.MINOR.PATCH on main — must match SCRIPT_VERSION
  4. release.yml creates GitHub release with tarball + individual assets

CI workflows

  • ci.yml: bash syntax, mirrors.txt format validation, Linux dry-run (stubs out Darwin check). ShellCheck is not in CI — it runs locally via the global shell-lint-fix pre-commit hook (~/.config/pre-commit/config.yaml), so every authorized commit is already linted before push.
  • release.yml: Validates tag matches SCRIPT_VERSION, lints, publishes release
  • update-mirrors.yml: Monthly Wikipedia scrape, opens PR if mirror set changed

Conventions

  • All log functions (info/success/warn/error) write to stderr so $() captures work correctly
  • MANAGED_MARKER comment in resolver files marks them as script-owned
  • Comparison of mirror lists is set-based (sorted), not order-based
  • Quad9 (9.9.9.9) is blocked by archive.today — do not use as example nameserver
  • Script requires GNU Bash features (mapfile, set -euo pipefail)

Headroom Learned Patterns

Auto-generated by headroom learn on 2026-04-07 — do not edit manually

Pre-commit Hooks

~2,000 tokens/session saved

  • A global pre-commit config at /Users/andrewrich/.config/pre-commit/config.yaml runs on every commit, including shellcheck (with --severity=warning) on shell scripts and YAML linting on GitHub Actions workflows.
  • Always run shellcheck --severity=warning <script> and validate YAML files before attempting git commit to avoid repeated failed commit attempts.

PR Merge Workflow

~1,500 tokens/session saved

  • Merging PRs via gh pr merge requires a local merge-lock authorization first: run ~/.claude/hooks/merge-lock.sh authorize <PR#> "<title>" before calling gh pr merge.
  • Do not attempt gh pr merge without user approval and the lock in place; the hook will block it with an error.

Shell Script Validation

~1,200 tokens/session saved

  • Always run bash -n <script> (syntax check) and shellcheck --severity=warning <script> before committing any shell script changes.
  • Fix all shellcheck warnings (not just errors) — unused variables, quoting issues, etc. — before committing.

Git Workflow

~500 tokens/session saved

  • Branch naming: claude/feature-<description>-<YYYYMMDD> and claude/release-<version>-<YYYYMMDD>.
  • Releases follow a branch-based flow: create claude/release-X.Y.Z-<date> branch, bump version in install.sh, push PR, merge, then tag vX.Y.Z on main.
  • GitHub Actions release.yml workflow handles the release after the tag is pushed.

Wikipedia API

~400 tokens/session saved

  • Direct WebFetch to en.wikipedia.org returns 403. Use the MediaWiki API: curl 'https://en.wikipedia.org/w/api.php?action=parse&page=<PageName>&prop=text&format=json'.

macOS DNS Resolver

~400 tokens/session saved

  • DNS resolver overrides go under /etc/resolver/ as per-domain files.
  • To flush DNS cache on macOS (including macOS 26+): sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder. Both commands are required and still valid as of macOS 26.

Security Policy

~300 tokens/session saved

  • Do NOT include curl | bash or equivalent "run directly without cloning" installation patterns in README or documentation — the user explicitly rejects this as a security anti-pattern.