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
40 changes: 40 additions & 0 deletions .chezmoiignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,43 @@ plugins.bin
plugins.lock
renovate.json
scripts
tests
provision
mise*.toml
mise*.lock
.miserc.toml
.dockerignore

# Preserve existing preferences even on the first apply before enrollment.
# After enrollment, missing paths stay ignored too, preserving deletions.
{{ $history := include "provision/dotfiles-history.json" | fromJson }}
{{ range concat $history.shared $history.macos }}
{{ if or (get $ "history" | default false) (stat (joinPath $.chezmoi.homeDir .)) }}
{{ . }}
{{ end }}
{{ end }}

{{ $harnesses := get . "harnesses" | default (list "opencode") }}
{{ if not (has "pi" $harnesses) }}
.pi
{{ end }}
{{ if not (has "claude" $harnesses) }}
.claude
{{ end }}
{{ if not (has "hermes" $harnesses) }}
.hermes
{{ end }}
{{ if not (has "goose" $harnesses) }}
.config/goose
{{ end }}
{{ if not (has "grok" $harnesses) }}
.grok
{{ end }}
{{ if or (ne .chezmoi.os "darwin") (and (hasKey . "services") (not .services)) }}
Library
{{ end }}
{{ if ne .chezmoi.os "darwin" }}
.config/ghostty
.config/phux-cockpit
.config/token-tach
{{ end }}
9 changes: 6 additions & 3 deletions .chezmoitemplates/agent-orchestration-agreement.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
## Delegation and coordination

- Default to self-direction. Resolve routine implementation, testing, tooling, naming, and reversible local choices from repository evidence and established conventions; state material assumptions and proceed instead of interrupting the user to reduce ordinary uncertainty.
- Own substantial tasks through `understand → decide → design → implement → verify → review → fix → final validation`. The parent personally reads load-bearing code, defines acceptance evidence, and remains accountable for the final diff and outcome.
- Delegation is a default capability when the harness provides it. Use it when parallel research, independent review, or a focused specialist improves evidence or throughput; do not delegate trivial work for ceremony.
- Roles describe purpose and authority, not capability prisons. Preserve each role's semantics while allowing it to delegate within the active session's capability ceiling.
- The parent owns decomposition, decisions, synthesis, validation, and acceptance. Child output is evidence, not automatic truth.
- The parent owns decomposition, decisions, synthesis, validation, and acceptance. Child output is evidence, not automatic truth. A writer handoff is intermediate until affected checks pass and an independent fresh-context review is dispositioned.
- Prefer one writer. Use deliberate worktrees or Blackbird path reservations when parallel writers are genuinely useful, and give each writer a non-overlapping scope.
- Use Blackbird as the durable mail, coordination, reservation, and work/run authority when available. Do not invent a second coordination protocol.
- Keep orchestration controls elastic. Concurrency, depth, budgets, and stop rules are circuit breakers, not targets or reasons to abandon obvious work.
- Recursive delegation is allowed only for distinct lanes that reduce the critical path. Keep orchestration controls elastic: concurrency, depth, budgets, and stop rules are circuit breakers, not targets or reasons to abandon obvious work.
- Use harness-local goal continuation for the active parent session, subagent missions for delegated recovery and accountability, and Blackbird for durable cross-session or cross-project mail, coordination, reservations, and work/run authority. Do not invent a competing protocol.
- Stop for the fixed publication/destructive-action boundary only after every safe local preparation, implementation, and validation step is complete; report the exact external action still requiring authority.
14 changes: 13 additions & 1 deletion .chezmoitemplates/agent-working-agreement.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!--
Single source of truth. Materialized into every agent's global instruction
file by chezmoi (`dot_claude/CLAUDE.md.tmpl`, `dot_codex/AGENTS.md.tmpl`,
file by chezmoi (`dot_claude/CLAUDE.md.tmpl` and
`dot_config/opencode/AGENTS.md.tmpl`). Edit HERE, then `chezmoi apply`.
Editing the materialized copies is a no-op — they get overwritten.
-->
Expand Down Expand Up @@ -49,3 +49,15 @@ reverse — pushing to a repo I don't own, force-pushing, cutting a release,
deleting remote state, anything destructive or hard to walk back — still gets
asked, every time. "Keep the ball rolling" governs the local, recoverable work
sitting in front of you.

## Complexity discipline

- Load and follow the shared `cyclomatic-complexity` skill for refactoring,
simplification, cleanup, code-quality review, deeply nested logic, god
functions, or any new nontrivial function with heavy branching.
- Measure touched functions before and after with project-native tooling and
thresholds when available. Preserve behavior and public APIs, run relevant
tests, and report the before/after complexity evidence.
- Never game the number with dense expressions or broaden the task into an
unrelated rewrite. Prefer guard clauses, named predicates, and small,
single-responsibility helpers that improve human readability.
76 changes: 76 additions & 0 deletions .chezmoitemplates/grok.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[ui]
max_thoughts_width = 120
fork_secondary_model = "grok-4.6"
yolo = false
compact_mode = false
permission_mode = "always-approve"
vim_mode = true

# Ox Alpha provider catalog. Keys remain machine-local environment state.
[model_providers.ox-opencode]
base_url = "https://opencode.ai/zen/v1"
api_backend = "chat_completions"
env_key = "OPENCODE_ZEN_API_KEY"
context_window = 1048576

[model_providers.ox-openrouter]
base_url = "https://openrouter.ai/api/v1"
api_backend = "chat_completions"
env_key = "OPENROUTER_API_KEY"
context_window = 1048576

[model_providers.ox-command]
base_url = "https://api.commandcode.ai/provider/v1"
api_backend = "chat_completions"
env_key = "COMMAND_CODE_API_KEY"
context_window = 1048576

[model_providers.ox-nous]
base_url = "http://127.0.0.1:8645/v1"
api_backend = "chat_completions"
env_key = "NOUS_API_KEY"
context_window = 1048576

[model_providers.ox-venice]
base_url = "https://api.venice.ai/api/v1"
api_backend = "chat_completions"
env_key = "VENICE_API_KEY"
context_window = 1048576

[model.ox-opencode]
model = "x-preview-f-free"
name = "Ox Alpha (OpenCode Zen; ZDR)"
description = "Limited-time free stealth preview with zero retention"
model_provider = "ox-opencode"
max_completion_tokens = 131072

[model.ox-openrouter]
model = "stealth/ox-alpha"
name = "Ox Alpha (OpenRouter)"
description = "Free stealth preview; upstream retains prompts and completions"
model_provider = "ox-openrouter"
max_completion_tokens = 131072

[model.ox-command]
model = "stealth/ox-alpha"
name = "Ox Alpha (Command Code)"
description = "Limited-time free stealth preview; not ZDR"
model_provider = "ox-command"
max_completion_tokens = 131072

[model.ox-nous]
model = "stealth/ox-alpha"
name = "Ox Alpha (Nous Portal)"
description = "Free-tier route; enable Nous Privacy Mode separately"
model_provider = "ox-nous"
max_completion_tokens = 131072

[model.ox-venice]
model = "stealth-ox-alpha"
name = "Ox Alpha (Venice)"
description = "Free beta route; anonymized third-party inference"
model_provider = "ox-venice"
max_completion_tokens = 131072

[models]
default = "grok-4.6"
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.git
**/node_modules
**/target
**/__pycache__
**/.DS_Store
**/.env
**/.env.*
**/*.local
**/*.local.toml
**/*.secret
**/secrets
graphify-out
artifacts
39 changes: 39 additions & 0 deletions .github/workflows/bootstrap-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Bootstrap acceptance
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
config:
strategy:
matrix:
os: [macos-15, ubuntu-24.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y zsh jq
- uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac # v2
with:
version: 2026.9.3
- run: bash tests/bootstrap/check.sh
- run: uv run --script tests/bootstrap/history_test.py
- run: bash tests/gha-local-smoke.sh
container:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
platform: linux/amd64
profile: container
- os: ubuntu-24.04-arm
platform: linux/arm64
profile: container,pi
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: bash tests/bootstrap/container.sh '${{ matrix.platform }}' '${{ matrix.profile }}'
13 changes: 5 additions & 8 deletions .github/workflows/dependency-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@ jobs:
run: |
jq empty renovate.json \
dot_config/opencode/create_package.json \
dot_config/opencode/plugin/autoresearch/package.json
zsh -n dot_zshrc dot_zshenv dot_zprofile
bash -n scripts/install-agent-stack.sh dot_local/bin/executable_dot-install-zsh-plugins
dot_config/opencode/opencode.jsonc
for file in dot_zshrc dot_zshenv dot_zprofile; do zsh -n "$file"; done
for file in scripts/install-agent-stack.sh dot_local/bin/executable_dot-install-zsh-plugins; do bash -n "$file"; done
- name: Validate Renovate semantics
run: npx --yes --package renovate@44.26.0 renovate-config-validator renovate.json
- name: Test OpenCode autoresearch plugin
working-directory: dot_config/opencode/plugin/autoresearch
run: |
npm ci --ignore-scripts
npm test
- name: Test lstags
working-directory: src/lstags
run: cargo test --locked
- name: Test pinned V2 goal plugin against the managed SDK
run: bash tests/bootstrap/goal-plugin.sh
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ bun.lock

# Compiled tool build artifacts (source is tracked, target/ is not)
src/*/target/

# Python test/import caches are runtime state, never chezmoi source.
__pycache__/
*.pyc
2 changes: 2 additions & 0 deletions .miserc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Native mise platform environments select mise.macos.toml / mise.linux.toml.
auto_env = true
64 changes: 49 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ the doc — don't quietly work around it.
## What this repo is

Personal dev substrate for one staff engineer, running on Mac (darwin/arm64)
and Raspberry Pi (linux/arm64). **chezmoi**-managed source-of-truth lives at
`~/dotfiles/`, materialized into `$HOME` via `chezmoi apply`. Everything is
and Raspberry Pi (linux/arm64). **Mise history** owns enrolled live preferences:
edit those in `$HOME` and its native watcher saves and synchronizes them. This
repository supplies provisioning code and first-install preference seeds.
**Chezmoi** retains machine-specific templates, executable tools and explicitly
managed application integrations. Everything is
**measured** (`dot-bench`), **checked** (`dot-doctor`), and **drift-detectable**
(`dot-audit`). The shell is treated as a substrate — every layer is observable.

Expand All @@ -23,7 +26,7 @@ This is a living organism. Local-maxima fixes get rejected.
1. **No hardcoded user paths in tracked files.** No `/Users/Patrick.Hall`, no
`/Users/phall` (use `$HOME`, or chezmoi template `{{ .chezmoi.homeDir }}`).
`dot-doctor` enforces this with a grep gate.
2. **`dot_zshenv` stays ≤30 lines.** Every non-interactive zsh invocation pays
2. **Live `.zshenv` and its `dot_zshenv` seed stay ≤30 lines.** Every non-interactive zsh invocation pays
its cost. Heavy init goes in `dot_zprofile` (login) or `dot_zshrc`
(interactive). Doctor enforces.
3. **Plugins clone OUTSIDE the repo** to `$XDG_DATA_HOME/zsh/plugins/`.
Expand Down Expand Up @@ -52,6 +55,18 @@ This is a living organism. Local-maxima fixes get rejected.

## Mental model

The initial editable preference set is in `provision/dotfiles-history.json`.
Enrollment seeds `~/.config/mise/conf.d/dotfiles-history.toml`, then that native
configuration is itself live-owned. The watcher saves into mise's bare Git
history and synchronizes with private `phall1/dotfiles-history`. Never connect
automatic history publication to this public provisioning repository.

`[data] history = true` in machine-local chezmoi configuration removes these
preferences from chezmoi ownership. Edits and intentional deletions survive
later bootstrap runs. Their `dot_*` copies are first-install seeds.

The remaining source-owned files follow this flow:

```
edit
┌──────────────────┐
Expand All @@ -73,7 +88,10 @@ This is a living organism. Local-maxima fixes get rejected.
/zsh/plugins/)
```

**Source of truth:** `~/dotfiles/dot_*` files. Edit here.
**Live preference source of truth:** the paths shown by `mise bootstrap dotfiles
paths`. Edit these directly and inspect native history.
**Generated/integration source of truth:** the remaining `~/dotfiles/dot_*`
templates, modifiers and executable tools. Edit these in the repository.
**Per-machine config:** `~/.config/chezmoi/chezmoi.toml`. Lives outside the
repo. Drives templating (`{{ .git.name }}`, etc.).
**Materialized state:** `$HOME` — populated by `chezmoi apply`. Real files,
Expand All @@ -85,35 +103,47 @@ not symlinks (chezmoi's default).

## The change loop (mandatory)

Bootstrap changes must pass `mise run check`, `uv run --script
tests/bootstrap/history_test.py`, and the affected disposable
`tests/bootstrap/container.sh` architecture/profile before live workstation
apply. The default selected harness is OpenCode V2; see `docs/BOOTSTRAP.md` for
optional harnesses and application-owned service/state boundaries.

For any non-trivial change:

```sh
# 1. Baseline — capture current state.
dot-doctor # expect: 0 failures, ≤2 warnings
dot-bench # expect: all metrics under PERF.md baselines

# 2. Make the edit in ~/dotfiles/dot_*.
$EDITOR ~/dotfiles/dot_zshrc
# 2. Edit live-owned preferences directly; native history autosaves them.
$EDITOR ~/.zshrc
dot-zcompile
# For provisioning code/generated targets, edit their repository source instead.

# 3. Preview.
chezmoi diff
mise bootstrap dotfiles status

# 4. Apply.
chezmoi apply
# (run_onchange_zcompile.sh.tmpl auto-fires when dot_zshrc/dot_zshenv/
# dot_p10k.zsh content changes.)
# This reconciles only source-owned files after native history enrollment.

# 5. Verify.
dot-doctor # any new failure = revert
dot-bench # >10% regression on any pinned metric = revert OR re-pin
# baseline with justification

# 6. Commit.
# 6. Native history autosaves preferences; force an immediate checkpoint if needed.
mise bootstrap dotfiles save
# Commit repository implementation changes separately.
git add <specific files>
git commit -m "feat(zsh): add fzf-tab group preview"
```

**If you skip steps 1, 5, or 6, you are doing it wrong.**
**Baseline and post-change checks remain mandatory.** Automatic history records
edits; it does not certify correctness. Use `mise bootstrap dotfiles rollback
<path>` and `undo` for preference recovery.

---

Expand Down Expand Up @@ -173,14 +203,16 @@ These are codified in `docs/PLAYBOOKS.md`. Cheat sheet:
| Add a doctor check | Drop a file in `checks/*.sh` (or `checks/<pkg>.sh` for per-tool) using `ok`/`warn`/`fail`/`require_bin`/`want_bin` helpers. See `checks/README.md`. |
| Add a bench metric | Already plumbed — zsh-bench output is parsed by metric name. Add a `key: value_ms` pair in `PERF.md` between `BASELINE_START`/`END` markers. |
| Add a new $HOME file | Create at `dot_<name>` (or under `dot_config/<subdir>/`) in source. `chezmoi apply`. |
| Add a brew package | Edit `scripts/bootstrap-darwin.sh` `brew_packages` array. Note: `scripts/` are NOT chezmoi-applied. |
| Add a brew package | Edit `provision/Brewfile` (host/tap tools) or `provision/Brewfile.desktop` (GUI apps). Mise invokes real Homebrew. |
| Onboard another machine | `bash ~/dotfiles/scripts/onboard.sh` (standalone download also documented in `docs/SELF-SAVING-DOTFILES.md`); assumes base tools and GitHub login exist. |
| Provision a workstation | `mise bootstrap`; inventories and the isolated test rig are documented in `docs/BOOTSTRAP.md`. |
| Add a CLAUDE.md hook / MCP server / skill | Edit `dot_claude/settings.json` for hooks/MCP. Drop a `dot_claude/skills/<name>/SKILL.md` for a skill. Run `/discover` after to confirm pickup. |
| Add a chezmoi template variable | Add to `~/.config/chezmoi/chezmoi.toml` under `[data]`. Reference as `{{ .key }}` in a `.tmpl` file. |
| Add per-machine override | Three options in increasing specificity: chezmoi.toml per machine → hostname branch in `dot_gitconfig.tmpl` → `~/.gitconfig-work` via `includeIf`. See docs/setup.md. |
| Set up the alt git identity on a new machine | `~/dotfiles/scripts/setup-alt-identity.sh` — interactive; writes `~/.gitconfig-alt`, generates `~/.ssh/id_ed25519_alt`, runs `gh auth login` into `~/.config/gh-alt/`. Untracked outputs are per-machine. |
| Apply the alt identity to a repo | `git identity alt` (one-shot per repo: sets local `user.name`/`email` from `~/.gitconfig-alt`, rewrites origin to the `github.com-alt` SSH alias). `git identity` shows current; `git identity primary` reverts. |
| Hit the alt GitHub API | `gh-alt ...` — same surface as `gh`, but `GH_CONFIG_DIR=~/.config/gh-alt` so it always operates on the alt account regardless of `gh auth switch` state. |
| Change the shell prompt | Edit `dot_p10k.zsh` directly OR re-run `p10k configure` and commit the result. |
| Change the shell prompt | Edit live `~/.p10k.zsh` or run `p10k configure`; native history autosaves it. Run `dot-zcompile` and `dot-bench`. |

---

Expand All @@ -196,8 +228,10 @@ These are codified in `docs/PLAYBOOKS.md`. Cheat sheet:
- **Reinventing the doctor's wheel** — the orchestrator (`dot-doctor`) is
intentionally dumb. New concerns are NEW files in `checks/`, not edits to
the orchestrator.
- **Editing `~/.zshrc` directly** — you'll lose it on next `chezmoi apply`.
Always edit `~/dotfiles/dot_zshrc`.
- **Editing an enrolled preference's seed expecting a live change** — live
preferences are authoritative. Edit `~/.zshrc`; its seed is for new installs.
- **Giving native tracking and chezmoi the same target** — doctor checks this
ownership overlap. Generated/mixed-runtime outputs need explicit handling.
- **Committing the rendered `~/.gitconfig`** — it's machine-specific output.
Edit `dot_gitconfig.tmpl` or `~/.config/chezmoi/chezmoi.toml` instead.
- **Adding "just for now" `set -x` / debug prints in tracked configs** — they
Expand Down Expand Up @@ -273,7 +307,7 @@ touch gets converted as part of the change.
## Reading more

- **`docs/ARCHITECTURE.md`** — the WHY behind every choice (P10k over Starship,
chezmoi over stow, raw zsh over antidote, mise rejected, etc.).
chezmoi over stow, raw zsh over antidote, mise provisioning, etc.).
- **`docs/PLAYBOOKS.md`** — full per-task recipes with exact commands.
- **`docs/setup.md`** — fresh machine bootstrap, per-machine identity layers.
- **`checks/README.md`** — doctor plugin architecture.
Expand Down
Loading
Loading