Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/repo-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ jobs:
# CI disagreed with a mise-pinned workstation and the gate was not
# reproducible. Bump both files together.
SHELLCHECK_VERSION: "0.11.0"
# tests/android/run.sh renders the managed chezmoi templates and hard-fails
# when chezmoi is absent, which is deliberate: a suite that skips in CI
# asserts nothing. The runner has no chezmoi, so the gate must install it.
# Keep in lockstep with the workstation's Homebrew chezmoi.
CHEZMOI_VERSION: "2.72.0"
steps:
- uses: actions/checkout@v4

Expand All @@ -36,5 +41,18 @@ jobs:
fi
shellcheck --version

- name: Install pinned chezmoi
run: |
set -euo pipefail
url="https://github.com/twpayne/chezmoi/releases/download/v${CHEZMOI_VERSION}/chezmoi_${CHEZMOI_VERSION}_linux_amd64.tar.gz"
curl -fsSL "$url" | tar -xz -C /tmp chezmoi
sudo install -m 0755 /tmp/chezmoi /usr/local/bin/chezmoi
installed="$(chezmoi --version | sed -n 's/^chezmoi version v\([0-9.]*\).*/\1/p')"
if [[ "$installed" != "$CHEZMOI_VERSION" ]]; then
echo "expected chezmoi ${CHEZMOI_VERSION}, got ${installed}" >&2
exit 1
fi
chezmoi --version

- name: Validate repository
run: scripts/validate-repo.sh
375 changes: 98 additions & 277 deletions AGENTS.md

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@ title: Claude Code Project Context
category: reference
component: ai-context
status: active
version: 3.1.0
last_updated: 2026-07-24
tags: [ai-cli, configuration, zsh, mcp]
version: 4.0.0
last_updated: 2026-08-12
tags: [ai-cli, configuration, mcp]
priority: medium
---

@AGENTS.md

## Claude-Specific Notes
## Claude-specific notes

- Prefer specialized tools: `Read` over `cat`, `Grep` over `rg`, `Glob` over `find`, `Edit` over `sed`
- zsh is the only managed interactive shell in this repo. Do not add fish config, fish syntax, or fish-specific aliases here.
- Run `scripts/validate-repo.sh` before committing (the gate CI runs; it uses
the shellcheck pinned in `.mise.toml`)
- Global agents and commands are available at `~/.claude/` and `~/.codex/` where tool-native config expects them
- Chezmoi templates use Go syntax, not Jinja2
- Project runtime and secret decisions belong in `.mise.toml` and `.envrc`
- Live secret-handling policy for this system is in `docs/secrets.md`
- Project MCP servers go in the host's project-native file (`.mcp.json` for
Claude Code; `.vscode/mcp.json` with a top-level `servers` object for VS
Code); `scripts/sync-mcp.sh` manages only the user-level global baseline
- The deny floor at `/Library/Application Support/ClaudeCode/managed-settings.json`
is root-owned and unconditional: it survives `bypassPermissions`, whereas a
`PreToolUse` hook is conditional. Its source of truth is `macos/claude-code/`
in this repo — edit there, then sudo-deploy; never edit the live file in
place. Read `docs/claude-macos-app.md` before changing any Claude config.
- Cowork rewrites `~/Library/Application Support/Claude/claude_desktop_config.json`
wholesale. Re-run `scripts/sync-mcp.sh` after using it.
- Claude Code's project-native MCP file is `.mcp.json` at a project root. A
project server written into `~/.claude.json` instead is swept by
`scripts/sync-mcp.sh`'s managed-key pass.
- Global agents, skills and commands live at `~/.claude/` (and `~/.codex/`)
where each tool natively looks for them. Do not re-create them under this
repo's `.claude/`.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ never committed — secrets live in 1Password and are resolved at launch.
| Shell | zsh startup, PATH, 15 `zshrc.d` modules, agentic-mode gating | `home/dot_zshenv.tmpl` → `home/dot_zshrc.tmpl` |
| Runtimes | global `mise` defaults | `home/dot_config/mise/` |
| Env | `direnv` helpers and policy | `home/dot_config/direnv/` |
| Android | canonical SDK root, Android CLI defaults, host/project capability reporting | `home/dot_androidrc.tmpl`, `ng-doctor android` |
| SSH (client) | `~/.ssh/config`, `conf.d/`, `allowed_signers` | `home/private_dot_ssh/` |
| Terminal | 14 iTerm2 dynamic profiles + color presets | `iterm2/`, `scripts/install-iterm2-profiles.sh` |
| Editor | reviewed subset of VS Code user settings, profiles, extensions | `vscode/`, `scripts/sync-vscode.sh` |
Expand All @@ -57,8 +58,9 @@ resolve server-side (§1, class "Account-managed") — both of which carry real
authorization and are invisible to every mechanism below. Enumeration there is
legibility, not governance.

1. **chezmoi** — `home/` is the source tree; 77 managed targets under `$HOME`.
Go templates, not Jinja2. Optional keys must use `| default`.
1. **chezmoi** — `home/` is the source tree; 78 managed targets under `$HOME`.
Go templates, not Jinja2. Guard possibly absent map keys with `hasKey` before
reading them; `| default` cannot recover from `missingkey=error`.
2. **Repo scripts** — `scripts/sync-mcp.sh`, `scripts/sync-vscode.sh`,
`scripts/install-iterm2-profiles.sh`, `scripts/mcp-usage-collector.sh`.
These write files chezmoi does not own, usually because the host application
Expand Down Expand Up @@ -94,8 +96,8 @@ iterm2/ dynamic profile and color-preset definitions
vscode/ managed user-setting keys, profile and extension manifests
macos/ root-owned configuration deployed by sudo, not chezmoi
policies/ canonical live policy; vendored byte-identically by a sibling repo
tests/ 8 suites (see validation caveat below)
docs/ 151 files; AGENTS.md is the authoritative index
tests/ 10 suites (see validation caveat below)
docs/ 154 files; docs/README.md is the authoritative annotated index
```

## Boundaries
Expand All @@ -121,13 +123,14 @@ Owned elsewhere, deliberately:
- `shellcheck` (pinned to 0.11.0 via `.mise.toml`) over tracked `*.sh` plus two
named templates
- `jq` shape checks on the MCP and VS Code JSON manifests
- `tests/system-update`, `tests/vscode`, `tests/mcp-vscode`, `tests/mcp-codex`
- `tests/system-update`, `tests/android`, `tests/vscode`, `tests/mcp-vscode`,
`tests/mcp-codex`, `tests/mcp-claude-desktop`
- `scripts/policy-lint.sh`, `scripts/check-instruction-bridge.sh`
- repo-contract greps (no fish surface, no stale path references)

**Known coverage gaps, stated rather than implied:** four of the eight suites —
**Known coverage gaps, stated rather than implied:** four of the ten suites —
`tests/git-identity-gate`, `tests/jr-style`, `tests/mise-config`,
`tests/policies` — are not invoked by the gate. `ng-doctor` reports 91 checks,
`tests/policies` — are not invoked by the gate. `ng-doctor` reports 101 checks,
a number of which are unimplemented skip stubs rather than assertions, so a
green summary is not by itself evidence of a healthy host. There is no secret or
PII scanner in the gate.
Expand Down
Loading
Loading