diff --git a/.opencode/agents/cheapest-go-worker.md b/.opencode/agents/cheapest-go-worker.md
new file mode 100644
index 0000000..6ca8993
--- /dev/null
+++ b/.opencode/agents/cheapest-go-worker.md
@@ -0,0 +1,28 @@
+---
+name: cheapest-go-worker
+description: "Use this project-local worker for Go implementation tasks assigned to the cheapest model tier. It is intended for straightforward Go/config changes with clear acceptance criteria."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: low
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ writing-go-code: allow
+ writing-go-tests: allow
+ testing-go-code: allow
+ linting-go-code: allow
+ building-go-binaries: allow
+---
+
+You are a project-local Go implementation worker running at the cheapest tier with low reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi`, `writing-go-code`, `writing-go-tests`, `testing-go-code`, `linting-go-code`, and `building-go-binaries`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant files, make only the requested changes, verify through the loaded testing, linting, and building skills, and report the changes and verification results.
+
+Do not run raw Go commands directly when a loaded skill provides the project command. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/cheapest-zsh-worker.md b/.opencode/agents/cheapest-zsh-worker.md
new file mode 100644
index 0000000..9da489f
--- /dev/null
+++ b/.opencode/agents/cheapest-zsh-worker.md
@@ -0,0 +1,24 @@
+---
+name: cheapest-zsh-worker
+description: "Use this project-local worker for Zsh or chezmoi shell-template tasks assigned to the cheapest model tier. It is intended for small, clear shell edits."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: low
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ configuring-zsh: allow
+---
+
+You are a project-local Zsh implementation worker running at the cheapest tier with low reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi` and `configuring-zsh`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant shell templates and docs, make only the requested changes, verify through the loaded skills, and report the changes and verification results.
+
+Preserve fast shell startup, guarded command checks, and existing template conventions. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/mid-tier-go-worker.md b/.opencode/agents/mid-tier-go-worker.md
new file mode 100644
index 0000000..67626e1
--- /dev/null
+++ b/.opencode/agents/mid-tier-go-worker.md
@@ -0,0 +1,28 @@
+---
+name: mid-tier-go-worker
+description: "Use this project-local worker for Go implementation tasks assigned to the mid-tier model. It is intended for Go changes with moderate integration, edge cases, or coordination risk."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: medium
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ writing-go-code: allow
+ writing-go-tests: allow
+ testing-go-code: allow
+ linting-go-code: allow
+ building-go-binaries: allow
+---
+
+You are a project-local Go implementation worker running at the mid-tier reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi`, `writing-go-code`, `writing-go-tests`, `testing-go-code`, `linting-go-code`, and `building-go-binaries`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant files, make only the requested changes, verify through the loaded testing, linting, and building skills, and report the changes and verification results.
+
+Do not run raw Go commands directly when a loaded skill provides the project command. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/mid-tier-zsh-worker.md b/.opencode/agents/mid-tier-zsh-worker.md
new file mode 100644
index 0000000..72a9fc8
--- /dev/null
+++ b/.opencode/agents/mid-tier-zsh-worker.md
@@ -0,0 +1,24 @@
+---
+name: mid-tier-zsh-worker
+description: "Use this project-local worker for Zsh or chezmoi shell-template tasks assigned to the mid-tier model. It is intended for shell startup, PATH, completion, and hook changes where regressions are costly."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: medium
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ configuring-zsh: allow
+---
+
+You are a project-local Zsh implementation worker running at the mid-tier reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi` and `configuring-zsh`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant shell templates and docs, make only the requested changes, verify through the loaded skills, and report the changes and verification results.
+
+Preserve fast shell startup, guarded command checks, and existing template conventions. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/most-capable-docs-worker.md b/.opencode/agents/most-capable-docs-worker.md
new file mode 100644
index 0000000..9c7efe1
--- /dev/null
+++ b/.opencode/agents/most-capable-docs-worker.md
@@ -0,0 +1,27 @@
+---
+name: most-capable-docs-worker
+description: "Use this project-local worker for documentation tasks assigned to the most capable model tier. It is intended for domain, architecture, and process documentation updates that require synthesizing implementation context."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: xhigh
+permission:
+ edit: allow
+ bash: deny
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ documenting-domain: allow
+ documenting-architecture: allow
+ documenting-business-processes: allow
+ documenting-components: allow
+---
+
+You are a project-local documentation worker running at the most capable tier with extra-high reasoning effort.
+
+Load `managing-chezmoi` immediately. Also load the relevant documentation skills for the assigned task when available: `documenting-domain`, `documenting-architecture`, `documenting-business-processes`, and `documenting-components`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Update only the requested documentation, keep claims grounded in the implementation and referenced plans, and preserve project terminology and document structure.
+
+Do not invent implemented behavior. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/most-capable-go-worker.md b/.opencode/agents/most-capable-go-worker.md
new file mode 100644
index 0000000..86b4107
--- /dev/null
+++ b/.opencode/agents/most-capable-go-worker.md
@@ -0,0 +1,28 @@
+---
+name: most-capable-go-worker
+description: "Use this project-local worker for Go implementation tasks assigned to the most capable model tier. It is intended for complex Go work requiring broad reasoning or high correctness confidence."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: xhigh
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ writing-go-code: allow
+ writing-go-tests: allow
+ testing-go-code: allow
+ linting-go-code: allow
+ building-go-binaries: allow
+---
+
+You are a project-local Go implementation worker running at the most capable tier with extra-high reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi`, `writing-go-code`, `writing-go-tests`, `testing-go-code`, `linting-go-code`, and `building-go-binaries`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant files, make only the requested changes, verify through the loaded testing, linting, and building skills, and report the changes and verification results.
+
+Do not run raw Go commands directly when a loaded skill provides the project command. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/most-capable-test-author-worker.md b/.opencode/agents/most-capable-test-author-worker.md
new file mode 100644
index 0000000..1d88cd0
--- /dev/null
+++ b/.opencode/agents/most-capable-test-author-worker.md
@@ -0,0 +1,29 @@
+---
+name: most-capable-test-author-worker
+description: "Use this project-local worker to write tests from acceptance criteria before implementation. It always runs on the most capable model tier because test intent and failure quality are critical."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: xhigh
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ test-driven-development: allow
+ writing-go-code: allow
+ writing-go-tests: allow
+ testing-go-code: allow
+ linting-go-code: allow
+ building-go-binaries: allow
+---
+
+You are a project-local test author worker running at the most capable tier with extra-high reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi`, `test-driven-development`, `writing-go-code`, `writing-go-tests`, and `testing-go-code`. Load `linting-go-code` and `building-go-binaries` when verification requires them.
+
+Write tests from the assigned sub-plan acceptance criteria before implementation. Confirm the tests fail for the intended reason when feasible, then report the test files changed and failure output. Do not implement production code unless the task explicitly asks for it.
+
+Do not run raw Go commands directly when a loaded skill provides the project command. Do not commit changes unless explicitly instructed.
diff --git a/.opencode/agents/most-capable-zsh-worker.md b/.opencode/agents/most-capable-zsh-worker.md
new file mode 100644
index 0000000..7b7f795
--- /dev/null
+++ b/.opencode/agents/most-capable-zsh-worker.md
@@ -0,0 +1,24 @@
+---
+name: most-capable-zsh-worker
+description: "Use this project-local worker for Zsh or chezmoi shell-template tasks assigned to the most capable model tier. It is intended for complex shell startup work requiring high correctness confidence."
+mode: subagent
+model: openai/gpt-5.5
+reasoningEffort: xhigh
+permission:
+ edit: allow
+ bash: allow
+ webfetch: deny
+ task:
+ "*": deny
+ skill:
+ managing-chezmoi: allow
+ configuring-zsh: allow
+---
+
+You are a project-local Zsh implementation worker running at the most capable tier with extra-high reasoning effort.
+
+Load these skills immediately before working: `managing-chezmoi` and `configuring-zsh`.
+
+Your task prompt and the assigned sub-plan are the source of truth. Read the relevant shell templates and docs, make only the requested changes, verify through the loaded skills, and report the changes and verification results.
+
+Preserve fast shell startup, guarded command checks, and existing template conventions. Do not commit changes unless explicitly instructed.
diff --git a/docs/architecture.md b/docs/architecture.md
index f30220f..a0e5145 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -27,9 +27,9 @@ The project has three major parts that interact through a clear data contract: a
### Shell Configuration (`dot_zshenv.tmpl`, `dot_zshrc.tmpl`, `private_dot_work/`)
-- **Responsibility**: Configure the runtime shell environment — PATH, tool integrations, plugins, [work environment][domain-work-env] loading
+- **Responsibility**: Configure the runtime shell environment — PATH, guarded tool integrations, plugins, [work environment][domain-work-env] loading
- **Boundaries**: These are chezmoi templates that produce shell files. At runtime, the generated files are plain shell scripts with no chezmoi dependency.
-- **Dependencies**: Generated by chezmoi from templates. At runtime, depends on installed tools (Homebrew, pyenv, sheldon, fzf, etc.)
+- **Dependencies**: Generated by chezmoi from templates. At runtime, progressively uses installed tools (Homebrew, sheldon, fzf, optional Python tooling, etc.) when available and skips guarded integrations when they are missing.
### Embedded Configuration (`installer/internal/config/`)
@@ -63,6 +63,7 @@ Generated shell files execute in Zsh's standard sourcing order: `.zshenv` (all s
| Chezmoi as dotfiles manager | Not bare git, stow, or yadm | Templates with conditional logic, mature tooling, good cross-platform support. The two-tier work environment model relies on chezmoi's template system. |
| Sheldon for Zsh plugins | Not oh-my-zsh framework | oh-my-zsh is used only for vendored function/plugin snippets (loaded as local files), not as a runtime framework. Sheldon is faster and more composable. |
| Deferred Homebrew loading | Split across `.zshenv` / `.zshrc` | Homebrew's `shellenv` eval is expensive (~50ms). Deferring it on macOS keeps non-interactive shells fast while still having brew available for interactive use. |
+| Python tooling as optional runtime surface | Offer `uv` through optional tools and keep shell startup guarded | The dotfiles do not manage Python versions or initialize Python version-manager shims. Existing `pip`, `poetry`, and `pipx` completions remain guarded, while brew-installed uv/uvx completions are discovered through Homebrew's completion directory. |
| Fresh clone on every apply | Delete and re-clone `~/.local/share/chezmoi` | Avoids merge conflicts and stale state. The installer always applies the latest from the configured branch. |
## Diagram
diff --git a/docs/context/uv-python-tooling-anchor.md b/docs/context/uv-python-tooling-anchor.md
new file mode 100644
index 0000000..c40e939
--- /dev/null
+++ b/docs/context/uv-python-tooling-anchor.md
@@ -0,0 +1,185 @@
+# uv Python Tooling Anchor
+
+## Intent
+
+Decide whether and how this dotfiles repo should move Python tooling from
+`pip`, `pipx`, `poetry`, and possibly `pyenv` toward `uv`, with the goal of
+reducing shell complexity while preserving portable machine setup behavior.
+
+## Quick Summary
+
+| Settled Direction | What It Means |
+|-------------------|---------------|
+| RFC accepted. | `docs/rfcs/RFC-switch-to-uv-python-tooling.md` R4 is the accepted design baseline. |
+| Implementation complete. | `uv` is configured as a brew-only optional tool, pyenv shell runtime behavior has been removed from the dotfiles source, and docs describe the uv-compatible optional Python tooling model. |
+| Directory-sensitive bare `python` selection is not required. | This removes the strongest reason to keep pyenv shims and shell integration. |
+| `uv` should be a normal optional installer tool. | The installer should offer `uv`, but not preselect or special-case it; adding recommendation tiers is not worth the complexity. |
+| Current repo has no Python project payload. | Searches found no `pyproject.toml`, `requirements*.txt`, `poetry.lock`, or `uv.lock`; Python references are shell integration, docs/examples, and packageresolver test fixtures. |
+| Avoid a full Python setup subsystem. | `uv` should provide enough Python capability on demand; preinstalling Python versions or migrating old Python state is over-engineering for current repo priorities. |
+| Keep useful Python completions. | Preserve `pip`, `poetry`, and guarded `pipx` completion caching; rely on Homebrew-provided `uv`/`uvx` completions in the MVP, with no installer-level zcompdump invalidation. |
+| MVP accepts brew-only `uv` installation. | Add `uv` through the existing optional-tool/package-map flow; apt/dnf fallback can be revisited later. |
+| No user-state migration. | Existing pyenv/pipx/Poetry state should be left alone; the installer is for initial bootstrapping, not ongoing state keeping. |
+
+## Current State
+
+- [x] Project docs and shell startup files were read for current architecture.
+- [x] Current Python shell integration was identified: pyenv shims in `.zshenv`, lazy pyenv initialization in `.zshrc`, cached completions for Poetry, pip, and pipx.
+- [x] `uv` documentation was checked for managed Python versions, `.python-version`, tools, auto-downloads, and executable behavior.
+- [x] User confirmed directory-sensitive bare `python` selection is not important in day-to-day use.
+- [x] User confirmed that if `uv` manages Python environments, the project installer should offer it.
+- [x] Official `uv` installation docs were checked: package-manager installs are supported, and the standalone installer can install into `~/.local/bin` with `UV_NO_MODIFY_PATH=1` to avoid editing shell profiles.
+- [x] Current repo usage was re-checked: there is no Python project dependency graph or Python-based installer path to preserve.
+- [x] User rejected a complete Python setup subsystem as unnecessary right now.
+- [x] User wants to keep `pip`, `poetry`, and guarded `pipx` completions, while adding `uv`/`uvx` completions and removing pyenv-specific shell behavior.
+- [x] User decided `uv` should not be preselected or treated as more important than other optional tools.
+- [x] Installer support was checked: standalone script installation exists as a pattern for chezmoi/Homebrew, but optional tools are currently package-manager-only.
+- [x] User accepted package-manager-only `uv` availability for now, with brew-only support matching current setup reality and existing brew-only optional tools.
+- [x] User confirmed no migration of existing pyenv, pipx, or Poetry user state is desired.
+- [x] RFC R2 was written and passed architecture, risk, and clarity re-review after preserving guarded pipx completions.
+- [x] User identified that brew-installed `uv`/`uvx` already provide completions through Homebrew; explicit uv/uvx completion caching is unnecessary for the brew-only MVP.
+- [x] R3 review found completion-cache ambiguity; R4 clarifies stale zcompdump behavior and requires a safer pipx argcomplete guard.
+- [x] RFC R4 passed architecture, risk, and clarity review with no concerns.
+- [x] User accepted RFC R4.
+- [x] Implementation plan `plans/features/switch-to-uv-python-tooling/` executed completely; final installer verification passed with `rtk go test ./...` from `installer/`.
+
+## Constraints
+
+- The repository is a chezmoi source directory; shell behavior changes should be made in source templates, not generated files.
+- Shell startup performance matters; avoid reintroducing eager Python tool initialization or mandatory uv startup work.
+- The installer is the only writer of chezmoi data, but Python tooling is currently not part of the installer data contract.
+- Existing design favors progressive enhancement: missing tools should not break shell startup.
+
+## Decisions
+
+### Python Version Selection Model
+
+**Decision:** The migration does not need to preserve pyenv-style automatic
+directory-sensitive switching for bare `python` or `pip` commands.
+
+**Reason:** The feature was added recently but has not been useful in practice;
+removing it simplifies shell startup and reduces pyenv-specific hacks.
+
+**Rejected:** Keep pyenv primarily to preserve automatic `cd project && python`
+behavior.
+
+**Reason rejected:** That behavior is not part of the user's actual workflow.
+
+**Reconsider if:** A future workflow depends on invoking bare `python` or `pip`
+inside project directories without routing through `uv` or an activated virtual
+environment.
+
+### Installer Ownership
+
+**Decision:** If `uv` becomes the preferred Python environment/tool manager, the
+installer should offer it as a normal optional tool, but the migration should
+not create a full Python provisioning subsystem or a special recommendation
+tier.
+
+**Reason:** The dotfiles should not depend on a manually installed external tool
+for the primary Python workflow. At the same time, the repo has no Python
+project payload today, so preinstalling Python versions, migrating existing
+pyenv/pipx state, designing a dedicated Python setup flow, or adding optional
+tool preselection is unnecessary.
+
+**Rejected:** Leave `uv` entirely to manual Homebrew/system installation while
+still making dotfiles assume `uv` workflows.
+
+**Reason rejected:** That would create an implicit dependency and weaken the
+portable bootstrap goal.
+
+**Rejected:** Add a recommended/default-selected optional-tool tier for `uv`.
+
+**Reason rejected:** It would be extra UX and installer complexity for a tool
+that should remain optional like the rest of the daily-use CLI tools.
+
+**Reconsider if:** The repo gains Python project dependencies, the installer
+starts requiring Python-managed tools during setup, or machines need a
+pre-provisioned Python runtime rather than on-demand `uv` behavior.
+
+### Shell Completions
+
+**Decision:** Keep low-cost completion caching for relevant legacy Python tools:
+retain `pip`, `poetry`, and guarded `pipx` completions. For the brew-only uv MVP,
+rely on Homebrew-provided `uv` and `uvx` completions instead of generating cached
+uv/uvx completions in `.zshrc`.
+
+**Reason:** Completion caching has minimal shell-startup cost and preserves
+compatibility with projects that still use Poetry, core `pip` workflows, or an
+installed `pipx` command. Homebrew's uv formula already generates uv/uvx
+completions, and the shell already adds Homebrew's zsh completion directory to
+`fpath`.
+
+**Decision:** Do not add installer-level `~/.zcompdump` invalidation in this RFC.
+
+**Reason:** The MVP relies on Homebrew completion files being present and on
+normal shell completion cache refresh behavior. Immediate completion freshness
+after installer-run `brew install uv` is not important enough to expand scope.
+
+**Rejected:** Invalidate zsh completion cache after optional-tool installs.
+
+**Reason rejected:** It is a broader installer behavior change that can be
+considered separately if completion freshness becomes important.
+
+**Rejected:** Remove legacy Python completions as part of the cleanup.
+
+**Reason rejected:** `pip` remains core Python tooling, and Poetry remains common
+enough that encountering existing projects is likely. `pipx` is no longer the
+preferred manager, but if it is installed, accurate completions are cheap and
+useful.
+
+**Reconsider if:** Completion generation becomes a measurable startup cost or
+the tools are no longer encountered in practice.
+
+### Optional Tool Availability
+
+**Decision:** Add `uv` through the existing optional tool/package mapping flow,
+with Homebrew support as the initial MVP. Do not add standalone installer
+fallback or unsupported-tool warnings for this RFC.
+
+**Reason:** This matches existing brew-only optional tools (`sheldon`, `eza`,
+`difftastic`) and is enough for the user's current setup pattern, where most
+machines use Homebrew.
+
+**Rejected:** Extend optional tools with alternate install methods before adding
+`uv`.
+
+**Reason rejected:** It is more work than the immediate need justifies.
+
+**Reconsider if:** Non-Homebrew Linux setups become common enough that missing
+`uv` materially hurts bootstrap completeness.
+
+### User State Migration
+
+**Decision:** Do not migrate, clean up, uninstall, or convert existing `pyenv`,
+`pipx`, or Poetry state.
+
+**Reason:** The installer is used for initial bootstrapping, not as an ongoing
+state keeper. Existing state may remain on disk without being managed by the
+dotfiles.
+
+**Rejected:** Convert pyenv Python versions, pipx-installed tools, or Poetry
+projects into uv-managed equivalents.
+
+**Reason rejected:** It would add risk and complexity outside the dotfiles'
+current responsibility.
+
+**Reconsider if:** The installer later becomes a state reconciliation tool or a
+dedicated cleanup/migration command is explicitly requested.
+
+## Open Questions
+
+No active open questions for the accepted RFC.
+
+## References
+
+- `dot_zshenv.tmpl`
+- `dot_zshrc.tmpl`
+- `docs/processes/shell-startup.md`
+- `installer/internal/config/tools.yaml`
+- `installer/internal/config/packagemap.yaml`
+- `docs/rfcs/RFC-switch-to-uv-python-tooling.md`
+- `plans/features/switch-to-uv-python-tooling/progress.md`
+- https://docs.astral.sh/uv/concepts/python-versions/
+- https://docs.astral.sh/uv/concepts/tools/
+- https://docs.astral.sh/uv/getting-started/installation/
+- https://docs.astral.sh/uv/reference/installer/
diff --git a/docs/domain.md b/docs/domain.md
index a57862f..ada5d57 100644
--- a/docs/domain.md
+++ b/docs/domain.md
@@ -88,12 +88,14 @@ See the [package resolution process][pkg-resolution] for the resolution flow fro
### Optional Tools
-Daily-use CLI tools (fzf, bat, eza, ripgrep, fd, difftastic, sheldon) that the installer can install at the user's request. Defined in [`tools.yaml`][tools-yaml], separate from prerequisites.
+Daily-use CLI tools (fzf, bat, eza, ripgrep, fd, difftastic, sheldon, uv) that the installer can install at the user's request. Defined in [`tools.yaml`][tools-yaml], separate from prerequisites.
- **Tool definition**: An entry in `tools.yaml` with a `name` ([abstract package key](#package-resolution)) and a human-readable `description`.
- **Not required**: Unlike prerequisites, optional tools are not needed for correct dotfiles setup. They enhance the shell experience but the system works without them.
- **Not persisted**: Tool selections are not saved to chezmoi data — tools are not part of the data contract.
-- **Platform-dependent availability**: Not all tools have package mappings for every manager. Some (e.g., `sheldon`, `eza`, `difftastic`) are brew-only.
+- **Platform-dependent availability**: Not all tools have package mappings for every manager. Some (e.g., `sheldon`, `eza`, `difftastic`, `uv`) are brew-only.
+
+`uv` is an optional Python tooling entrypoint in this model. It is available through the optional-tools flow only where package resolution supports it; it is not required for dotfiles setup, is not written to chezmoi data, and does not imply installer-managed Python versions or migration of existing Python tool state.
See the [optional tools installation process][tools-install] for selection, filtering, and installation details.
diff --git a/docs/processes/shell-startup.md b/docs/processes/shell-startup.md
index ce30f7b..cb19b8c 100644
--- a/docs/processes/shell-startup.md
+++ b/docs/processes/shell-startup.md
@@ -2,7 +2,7 @@
## Overview
-Describes how the Zsh shell environment initializes, including Homebrew loading, PATH setup, work environment activation, and plugin loading. The startup is split across `.zshenv` (all shells) and `.zshrc` (interactive shells) with an emphasis on keeping non-interactive shell startup fast.
+Describes how the Zsh shell environment initializes, including Homebrew loading, PATH setup, guarded completion setup, work environment activation, and plugin loading. The startup is split across `.zshenv` (all shells) and `.zshrc` (interactive shells) with an emphasis on keeping non-interactive shell startup fast.
## Trigger
@@ -31,10 +31,7 @@ flowchart TD
D1 --> D4["BREW_LOADED=true"]
D2 --> D4
D3 --> D4
- D4 --> E{~/.pyenv exists?}
- E -- Yes --> E1[Add pyenv shims to PATH]
- E -- No --> F
- E1 --> F{Linux + mold?}
+ D4 --> F{Linux + mold?}
F -- Yes --> F1[Set RUSTFLAGS for mold]
F -- No --> G
F1 --> G{work_env?}
@@ -51,8 +48,7 @@ flowchart TD
L -- Yes --> L1[load_brew_env now]
L -- No --> M
L1 --> M[Aliases & tool PATHs]
- M --> N[Lazy pyenv init]
- N --> O[Cache completions]
+ M --> O[Cache guarded completions]
O --> P{work_env?}
P -- Yes --> P1[Source work RC extension]
P -- No --> Q
@@ -76,37 +72,35 @@ flowchart TD
### `.zshenv` Phase (All Shells)
-1. **Set base PATH** — Add `~/.local/bin`, `~/bin`, `/usr/local/bin`
+1. **Set base PATH** — Add `~/.local/bin`, `~/bin`, `/usr/local/bin` with duplicate removal
2. **Determine Homebrew location** — Based on OS and architecture:
- Linux: `/home/linuxbrew/.linuxbrew`
- macOS arm64: `/opt/homebrew`
- macOS x86: `/usr/local`
-3. **Handle Homebrew loading** — Platform-dependent behavior (only if `BREW_LOADED` is not already set). See [deferred Homebrew loading][domain-deferred-brew] for the concept.
+3. **Handle Homebrew loading** — Platform-dependent behavior (only if `BREW_LOADED` is not already set). See [deferred Homebrew loading][domain-deferred-brew] for the concept. When Homebrew's `shellenv` is evaluated, `~/.local/bin` and `~/bin` are re-prepended so user-local defaults such as uv-managed `python`/`python3` symlinks take precedence over Homebrew binaries.
- **macOS (non-devbox)**: Set `DEFER_BREW_LOAD=true` — postpone the expensive `shellenv` eval to `.zshrc`
- **Linux**: Call `load_brew_env` immediately — PATH consistency is more important than startup speed
- **Devbox**: Add brew directories to PATH directly — no `eval` needed
- Set `BREW_LOADED=true` to prevent double-loading
-4. **Set up pyenv** — If `~/.pyenv` exists, add shims and bin directories to PATH (fast, no eval)
-5. **Set up Rust linker** — On Linux with mold available, configure `RUSTFLAGS` to use mold
-6. **Load work environment** — If `personal.work_env` is true, see the [work environment loading process][work-env-loading]
+4. **Set up Rust linker** — On Linux with mold available, configure `RUSTFLAGS` to use mold
+5. **Load work environment** — If `personal.work_env` is true, see the [work environment loading process][work-env-loading]
### `.zshrc` Phase (Interactive Shells Only)
1. **Powerlevel10k instant prompt** — Load cached prompt for immediate visual feedback
2. **Set editor and locale** — `VISUAL`, `EDITOR`, `LANG`, `LC_ALL`
3. **Configure history** — History file, size, append mode
-4. **Set up completions** — Configure fpath, load Homebrew completions, run `compinit -C` (cached)
+4. **Set up completions** — Configure fpath, add Homebrew's `share/zsh/site-functions` directory before `compinit`, then run `compinit -C` (cached).
5. **Complete deferred brew loading** — If `DEFER_BREW_LOAD` is `true`, call `load_brew_env` now
6. **Set up aliases** — Git, neovim, GPG unlock
-7. **Configure pyenv** — Lazy initialization: full pyenv shell integration is loaded only when a Python-related command is detected or `.python-version`/`.envrc` is found in the directory tree
-8. **Add tool PATHs** — Cargo, Go, Ruby gems, clang-format, bun (conditional on tool availability)
-9. **Cache completions** — Generate completion files for cargo, poetry, pip, pipx only if missing or older than 7 days
-10. **Source work RC extension** — If `personal.work_env` is true, source `WORK_ZSH_RC_EXTENSION` (see [work environment loading][work-env-loading])
-11. **Load oh-my-zsh functions and plugins** — Vendored git functions, key-bindings, git, dotenv plugins
-12. **Load sheldon plugins** — `eval "$(sheldon source)"` loads the plugin set defined in [`plugins.toml`][sheldon-plugins]
-13. **Load Powerlevel10k theme** — Source `~/.p10k.zsh`
-14. **Configure fzf and fzf-tab** — Fuzzy finder integration with completion system
-15. **VS Code shell integration** — If running inside VS Code terminal, load VS Code's shell integration script
+7. **Add tool PATHs** — Cargo, Go, Ruby gems, clang-format, bun (conditional on tool availability)
+8. **Cache completions** — Generate completion files for cargo, poetry, pip, pipx only if missing or older than 7 days. `pipx` completion generation requires both `pipx` and `register-python-argcomplete` to exist before invoking argcomplete.
+9. **Source work RC extension** — If `personal.work_env` is true, source `WORK_ZSH_RC_EXTENSION` (see [work environment loading][work-env-loading])
+10. **Load oh-my-zsh functions and plugins** — Vendored git functions, key-bindings, git, dotenv plugins
+11. **Load sheldon plugins** — `eval "$(sheldon source)"` loads the plugin set defined in [`plugins.toml`][sheldon-plugins]
+12. **Load Powerlevel10k theme** — Source `~/.p10k.zsh`
+13. **Configure fzf and fzf-tab** — Fuzzy finder integration with completion system
+14. **VS Code shell integration** — If running inside VS Code terminal, load VS Code's shell integration script
### Failure Scenarios
@@ -124,17 +118,24 @@ flowchart TD
- **Handling**: The `[[ -r ... ]]` guard skips sourcing. Shell starts without work config.
- **User impact**: Work-specific environment variables and paths won't be set. Run the installer with `--work-env` to regenerate.
-#### pyenv not installed
+#### Optional Python tooling not installed
-- **Trigger**: `~/.pyenv` directory doesn't exist
-- **At step**: `.zshenv` step 4, `.zshrc` step 7
-- **Handling**: Conditional checks skip all pyenv setup
-- **User impact**: None — pyenv features simply aren't available
+- **Trigger**: `uv`, `pip`, `poetry`, `pipx`, or `register-python-argcomplete` is not installed
+- **At step**: `.zshrc` steps 4 and 8
+- **Handling**: Guarded completion setup skips missing tools. Brew-installed uv/uvx completions are available only when Homebrew provides completion files on `fpath` and zsh's completion cache recognizes them.
+- **User impact**: Shell startup succeeds. Missing tools simply do not provide completions or commands until the user installs or activates them.
+
+#### Stale zsh completion cache after Homebrew uv installation
+
+- **Trigger**: `uv` is installed by Homebrew outside the interactive `brew` wrapper path, but `compinit -C` reuses an older `~/.zcompdump`
+- **At step**: `.zshrc` step 4
+- **Handling**: The Homebrew completion directory remains on `fpath`, but zsh may not immediately discover new `_uv` or `_uvx` completion files until the cache is refreshed
+- **User impact**: uv commands work if installed, but uv/uvx completions may appear only after normal completion cache refresh or manual cache invalidation
## State Changes
- **Environment variables**: PATH, BREW_HOME, BREW_LOADED, DEFER_BREW_LOAD, WORK_ENV_LOADED, and tool-specific vars
-- **Shell functions**: `load_brew_env`, `brew` wrapper (invalidates completion cache on install/uninstall), pyenv lazy loaders
+- **Shell functions**: `load_brew_env`, `brew` wrapper (invalidates completion cache on install/uninstall)
- **Completion system**: `compinit` initialized with cache, fpath populated
## Dependencies
diff --git a/docs/rfcs/RFC-switch-to-uv-python-tooling.md b/docs/rfcs/RFC-switch-to-uv-python-tooling.md
new file mode 100644
index 0000000..2a0539a
--- /dev/null
+++ b/docs/rfcs/RFC-switch-to-uv-python-tooling.md
@@ -0,0 +1,432 @@
+# RFC-0001: Switch To uv For Python Tooling
+
+Status: Accepted
+Revision: R4
+Last Updated: 2026-05-08
+
+## Review Record
+
+| Reviewer | Scope | Status | Notes |
+|----------|-------|--------|-------|
+| `rfc-architect-reviewer` | Architecture, boundaries, contracts, current-state fit, planning readiness | Passed | `docs/rfcs/reviews/RFC-0001.rfc-architect-reviewer.md`; R4 passed with no concerns. |
+| `rfc-risk-reviewer` | Technical risks, migration, compatibility, rollback, hidden complexity | Passed | `docs/rfcs/reviews/RFC-0001.rfc-risk-reviewer.md`; R4 passed with no concerns. |
+| `rfc-clarity-reviewer` | Clarity and actionability | Passed | `docs/rfcs/reviews/RFC-0001.rfc-clarity-reviewer.md`; R4 passed with no concerns. |
+
+## Summary
+
+This RFC changes the dotfiles' Python tooling posture from pyenv-centered shell
+integration to uv-compatible, on-demand Python tooling. The repo does not
+contain Python project dependencies or a Python-based installer path today, so
+the chosen design is intentionally small: offer `uv` as a normal optional
+installer tool, remove pyenv-specific shell startup behavior, and keep low-cost
+completions for Python tools that are still useful in existing projects.
+
+The design does not introduce a dedicated Python setup subsystem. It does not
+preinstall Python versions, migrate existing `pyenv` or `pipx` state, convert
+Poetry projects, or add standalone uv installation fallback for non-Homebrew
+systems. The immediate goal is to make uv available where the current optional
+tools mechanism supports it, simplify shell startup, and leave future Python
+needs to uv's on-demand workflows when uv is installed. No generated shell
+behavior may require uv to be present.
+
+## Problem
+
+The current shell configuration contains pyenv-specific behavior even though
+pyenv's main benefit in this setup, automatic directory-sensitive switching for
+bare `python` and `pip`, is not part of the user's actual workflow. This creates
+shell complexity without corresponding value:
+
+- `.zshenv` adds pyenv shims and pyenv's binary directory when `~/.pyenv`
+ exists.
+- `.zshrc` lazily initializes pyenv and pyenv-virtualenv based on directory
+ markers or Python-related commands.
+- A local `pyenv-shell` shim exists to work around pyenv shell-integration
+ behavior.
+
+At the same time, uv has become the preferred tool the user wants available for
+Python environments, Python-based tools, and ad hoc Python work. The dotfiles
+should shift toward uv-compatible shell behavior without over-engineering a full
+Python lifecycle manager inside the installer or making shell startup depend on
+uv availability.
+
+## Goals
+
+- Make `uv` available through the existing installer optional-tools flow where
+ the active package manager supports it.
+- Remove pyenv-specific shell startup behavior from the dotfiles.
+- Use Homebrew-provided uv/uvx completions when uv is installed by Homebrew.
+- Preserve `pip`, `poetry`, and guarded `pipx` completions because they remain
+ useful for core Python workflows, existing projects, and machines where pipx
+ is still installed.
+- Keep shell startup uv-compatible rather than uv-dependent.
+- Keep the migration small, reversible, and aligned with the existing optional
+ tools architecture.
+
+## Non-Goals
+
+- Do not add a dedicated Python setup subsystem to the installer.
+- Do not preinstall Python versions with `uv python install`.
+- Do not migrate, delete, uninstall, or convert existing `pyenv`, `pipx`, or
+ Poetry state.
+- Do not convert existing Poetry projects to uv projects.
+- Do not preserve pyenv-style automatic directory-sensitive switching for bare
+ `python` or `pip`.
+- Do not add optional-tool preselection, recommendation tiers, or special
+ prompt behavior for `uv`.
+- Do not add standalone uv installer fallback for non-Homebrew active package
+ managers in this RFC.
+
+## Constraints
+
+- This repository is the chezmoi source directory; shell behavior changes belong
+ in source templates such as `dot_zshenv.tmpl` and `dot_zshrc.tmpl`.
+- The installer writes chezmoi data, but Python tooling is not part of the
+ current chezmoi data contract.
+- Shell startup should stay fast and progressively skip unavailable tools.
+- The existing optional-tools flow is package-manager-backed and non-fatal.
+- Existing brew-only optional tools are silently filtered out when the active
+ package manager is not Homebrew.
+- The installer is used for initial bootstrapping, not ongoing state keeping.
+- The user has explicitly accepted Homebrew-only uv availability for the MVP
+ because most target setups use Homebrew.
+- The user has explicitly confirmed that directory-sensitive bare `python`
+ switching is not important in day-to-day use.
+
+## Current State
+
+The project has three relevant boundaries:
+
+- The Go installer bootstraps prerequisites, applies dotfiles, and optionally
+ installs selected CLI tools.
+- Chezmoi templates define shell runtime behavior through files such as
+ `dot_zshenv.tmpl` and `dot_zshrc.tmpl`.
+- The generated shell files configure runtime PATH, completions, Homebrew
+ loading, work environment loading, and tool integrations.
+
+Python support is currently shell-centric:
+
+- `dot_zshenv.tmpl` adds `~/.pyenv/shims` and `~/.pyenv/bin` to `PATH` when
+ `~/.pyenv` exists.
+- `dot_zshrc.tmpl` lazily initializes pyenv and pyenv-virtualenv when a Python
+ marker or Python-related command is detected.
+- `dot_zshrc.tmpl` caches completions for `poetry`, `pip`, and `pipx`.
+- `private_dot_local/bin/executable_pyenv-shell` exists only to make `pyenv
+ shell` behave when full shell integration is not loaded.
+
+The optional tools system is package-manager-centered:
+
+- `installer/internal/config/tools.yaml` lists optional tool names and
+ descriptions.
+- `installer/internal/config/packagemap.yaml` maps abstract tool names to
+ package-manager-specific names.
+- During installation, `installOptionalTools` pre-filters tools by resolving
+ them for the active package manager.
+- Tools without a valid mapping for the active package manager are dropped
+ before the interactive prompt and before `--install-tools` installation.
+- Existing tools such as `sheldon`, `eza`, and `difftastic` are brew-only and do
+ not appear when the active package manager is not Homebrew.
+
+The repository currently has no Python project payload to preserve. Searches
+found no `pyproject.toml`, `requirements*.txt`, `poetry.lock`, or `uv.lock` in
+the repo. Python references are limited to shell integration, documentation,
+examples, and package-resolver test fixtures.
+
+## Chosen Approach
+
+Adopt uv as the preferred Python tooling entrypoint while keeping the change
+inside existing boundaries:
+
+- Add `uv` to `tools.yaml` as a normal optional tool.
+- Add a Homebrew mapping for `uv` in `packagemap.yaml`.
+- Let non-Homebrew active package managers continue using existing unsupported-
+ tool behavior: `uv` is filtered out when no mapping exists.
+- Remove pyenv-specific PATH setup, lazy initialization, and local shim support.
+- Keep cached completions for `pip`, `poetry`, and `pipx`.
+- Rely on Homebrew-provided completions for `uv` and `uvx` in the MVP.
+- Document the shell startup process as uv-compatible rather than pyenv-oriented.
+
+This design treats uv like other optional tools for installation while treating
+pyenv as no longer part of the dotfiles' preferred shell runtime model.
+
+## Decision Summary
+
+| Decision | Rationale | Consequence |
+|----------|-----------|-------------|
+| Use uv as the preferred Python tooling entrypoint when available. | uv covers on-demand Python versions, project environments, and Python CLI tools without pyenv shell shims. | Python work should route through uv workflows when project-specific behavior is needed, but shell startup must not require uv. |
+| Do not preserve automatic bare `python` switching. | Settled user decision: the user does not rely on this behavior. | pyenv shell integration can be removed without replacing its directory-sensitive shim model. |
+| Install uv through optional tools. | The repo has no Python payload requiring a stronger bootstrap dependency. | uv remains user-selected and non-fatal like other optional tools. |
+| Support Homebrew first. | The existing package-map flow already supports brew-only tools, and settled user decision accepts brew-only support for the MVP. | uv is hidden for non-Homebrew active package managers until explicit mappings or fallback install support are added. |
+| Keep `pip`, `poetry`, and `pipx` completion caching. | They are low-cost and useful for existing Python projects or machines where pipx remains installed. | Removing pyenv and adding uv does not remove useful legacy completions. |
+| Rely on Homebrew for uv/uvx completions. | The Homebrew uv formula generates uv and uvx completions, and `.zshrc` already adds Homebrew's zsh completion directory to `fpath`. | No explicit uv/uvx completion cache generation is needed for the brew-only MVP. |
+| Do not migrate user state. | The installer is not an ongoing state keeper. | Existing pyenv/pipx/Poetry files remain untouched. |
+
+## Proposed Architecture
+
+The proposed architecture keeps Python tooling split across the same lifecycle
+boundaries as the rest of the dotfiles:
+
+- Installer lifecycle: `uv` is offered during optional tools installation when
+ the active package manager can resolve it.
+- Template lifecycle: shell templates stop adding pyenv runtime behavior and
+ retain guarded completion cache generation for pip/Poetry/pipx. uv/uvx
+ completions come from Homebrew's zsh completion directory when uv is installed
+ by Homebrew.
+- Runtime lifecycle: shells no longer initialize pyenv, add pyenv shims, or
+ depend on a pyenv workaround shim. Shell startup remains valid without uv;
+ users invoke uv directly when it is installed and Python project or tool
+ behavior is needed.
+
+No new chezmoi data keys, installer state files, or persistent migration records
+are introduced.
+
+## Components And Responsibilities
+
+| Component / Boundary | Responsibility | Current / New / Modified | Notes |
+|----------------------|----------------|--------------------------|-------|
+| `installer/internal/config/tools.yaml` | Lists optional tools shown by the installer after package-manager filtering. | Modified | Add `uv` with a user-facing description. |
+| `installer/internal/config/packagemap.yaml` | Maps abstract optional tool names to package-manager package names. | Modified | Add `uv` for Homebrew only in the MVP. |
+| `dot_zshenv.tmpl` | Defines fast environment setup for all Zsh sessions. | Modified | Remove pyenv PATH/shim setup. |
+| `dot_zshrc.tmpl` | Defines interactive shell behavior and completion caching. | Modified | Remove lazy pyenv initialization; keep pip/Poetry/pipx completion caching; keep Homebrew completion loading for brew-installed uv/uvx. |
+| `private_dot_local/bin/executable_pyenv-shell` | Provides a pyenv-specific workaround command. | Removed | No longer needed once pyenv shell integration is removed. |
+| `docs/processes/shell-startup.md` | Documents shell startup behavior. | Modified | Update pyenv-oriented current-state documentation to the uv-compatible runtime model. |
+| `docs/domain.md` | Describes optional tools and domain concepts. | Modified | Keep optional-tool documentation accurate after adding uv to the configured optional tools. |
+| `docs/architecture.md` | Describes shell runtime dependencies. | Modified | Stop naming pyenv as a shell runtime dependency; describe Python tooling as optional and guarded. |
+
+## Contracts And Interfaces
+
+The optional tools contract remains unchanged:
+
+- Tool definitions remain entries in `tools.yaml`.
+- Package resolution remains driven by `packagemap.yaml`.
+- Unsupported tools remain filtered out before selection.
+- `--install-tools` continues to install all currently resolvable tools.
+- Interactive selection continues to show all currently resolvable tools
+ unselected by default.
+
+The shell runtime contract changes by removal rather than replacement:
+
+- The dotfiles no longer guarantee that pyenv shims are placed before other
+ Python executables.
+- The dotfiles no longer guarantee that `~/.pyenv/bin` is placed on `PATH`, so
+ explicit `pyenv` commands are available only if the user manages pyenv outside
+ these dotfiles.
+- The dotfiles no longer initialize pyenv or pyenv-virtualenv in interactive
+ shells, including for `.python-version`, `.envrc`, or explicit `pyenv*`
+ command detection.
+- The dotfiles no longer provide a `pyenv-shell` workaround command.
+- The dotfiles retain guarded completion cache hooks for `pip`, `poetry`, and
+ `pipx`.
+- The dotfiles do not generate cached uv/uvx completions in the MVP. Brew-
+ installed uv/uvx completions are provided through Homebrew's zsh completion
+ directory, which is already added to `fpath` before `compinit`.
+- Newly installed Homebrew completions may not be visible immediately if
+ `compinit -C` reuses an existing `~/.zcompdump`; the MVP does not add installer-
+ level zcompdump invalidation.
+- pipx remains completion-supported when installed, but it is no longer the
+ preferred Python tool manager in the dotfiles' documentation or direction.
+
+The completion contract is intentionally concrete:
+
+- `pip` and `poetry` completion generation remains guarded by command existence
+ checks and stale cache checks, matching the existing completion-cache pattern.
+- `pipx` completion generation is guarded by both `pipx` and
+ `register-python-argcomplete` availability, plus the same stale cache check.
+- uv/uvx completion behavior follows the Homebrew formula for the brew-only MVP.
+- If future work adds non-Homebrew uv installation, that work must decide whether
+ to generate uv/uvx completions explicitly or rely on that install method.
+
+## Data And State
+
+No new durable data is introduced.
+
+Existing user-owned state is intentionally left untouched:
+
+- `~/.pyenv` may continue to exist but is no longer managed or placed on PATH by
+ the dotfiles.
+- Existing pipx tool environments may continue to exist and can still receive
+ guarded completion refreshes when both the `pipx` command and
+ `register-python-argcomplete` helper are available.
+- Existing completion cache files for tools that are no longer installed may
+ remain; they are residual user state and are not authoritative for the current
+ dotfiles source.
+- Existing Poetry projects and Poetry user configuration are not modified.
+- uv-managed Python versions, caches, and tools are created later by uv itself
+ when the user invokes uv workflows.
+
+## Control And Data Flow
+
+During installer optional tools setup:
+
+1. The installer loads `tools.yaml`.
+2. The package resolver tries to resolve each tool for the active package
+ manager.
+3. `uv` resolves on Homebrew systems through the new `packagemap.yaml` entry.
+4. `uv` does not resolve when the active package manager is not Homebrew in the
+ MVP and is filtered out like existing brew-only tools.
+5. Interactive users may select `uv` if it is visible; `--install-tools` installs
+ it automatically only when it is resolvable.
+
+During shell startup:
+
+1. `.zshenv` performs base PATH, Homebrew, Rust, and work-environment setup
+ without pyenv-specific PATH mutation.
+2. `.zshrc` initializes completions and interactive shell integrations without
+ pyenv lazy hooks.
+3. Completion cache generation creates or refreshes `pip` and `poetry`
+ completion files only when the corresponding command is available and the
+ cache is missing or stale.
+4. `pipx` completion cache generation also requires
+ `register-python-argcomplete` to be available before refreshing `_pipx`.
+5. Brew-installed uv/uvx completions are discovered through Homebrew's zsh
+ completion directory on `fpath`; `.zshrc` does not generate uv/uvx completion
+ cache files in the MVP.
+6. If `~/.zcompdump` is stale, Homebrew-provided uv/uvx completions may not be
+ discovered until the completion cache is refreshed. The existing interactive
+ `brew` shell wrapper handles future interactive brew changes, but installer-
+ driven package installs do not gain a new cache invalidation mechanism in this
+ RFC.
+7. Python project behavior is handled by explicit uv commands or by whatever
+ Python environment the user activates outside the dotfiles.
+
+## Failure Modes And Recovery
+
+| Failure Mode | Expected Behavior | Recovery / User Impact |
+|--------------|-------------------|------------------------|
+| `uv` has no mapping for the active package manager. | It is filtered out before prompt/installation. | User can install uv manually or wait for future standalone fallback support. |
+| Homebrew installation of `uv` fails. | Optional tool installation records the failure and continues with other tools. | Main installation remains successful; user can retry or install manually. |
+| `uv` is not installed at shell startup. | No uv/uvx completions are available from Homebrew. | Shell starts normally without uv completions. |
+| Homebrew installs uv but zsh completion cache is stale. | `_uv` and `_uvx` files may exist in Homebrew's completion directory but not be discovered by `compinit -C`. | Completions appear after the zsh completion cache is refreshed; this RFC does not add installer-level cache invalidation. |
+| Existing project expects pyenv shims, `pyenv` on PATH, or pyenv initialization from `.envrc`/`.python-version`. | Dotfiles no longer provide those shims, PATH entries, initialization hooks, or `pyenv-shell` workaround behavior. | User can invoke uv workflows, activate a project environment, or manage pyenv PATH/init outside these dotfiles. |
+| Existing pipx-installed command remains on PATH from prior user state. | Dotfiles do not remove it and continue guarded completion refreshes when pipx and `register-python-argcomplete` are available. | Command may still work if user state provides it; pipx remains completion-supported but is not the preferred tool manager. |
+
+## Security, Privacy, And Permissions
+
+This RFC does not add a new download script, credential surface, or privilege
+model. uv installation uses the same package-manager path as other optional
+tools in the MVP. Future standalone installer support would require a separate
+security review because it would download and execute an external installer
+script.
+
+## Operations And Observability
+
+The installer observability model remains unchanged:
+
+- Unsupported optional tools are silently filtered before prompt/installation.
+- Installation failures for selected tools are reported in the optional-tools
+ summary.
+- Shell completion generation remains silent and guarded by command existence
+ checks.
+
+No new metrics, logs, or state files are introduced.
+
+## Compatibility And Migration
+
+This is a forward-looking shell behavior migration, not a user-state migration.
+
+Compatibility expectations:
+
+- Existing machines with pyenv installed are not modified on disk.
+- Existing shells generated after this change will stop adding pyenv behavior.
+- Existing projects or scripts that call `pyenv` directly must manage pyenv PATH
+ and initialization outside these dotfiles.
+- Existing Poetry and pip workflows remain supported at the completion level.
+- Existing pipx workflows are not actively broken; pipx remains
+ completion-supported when installed and when `register-python-argcomplete` is
+ available, but is no longer the preferred Python tool manager.
+- Existing cached completions for removed tools or pyenv-related target files
+ may remain as residual state; this RFC does not require cleanup.
+- Non-Homebrew systems continue to behave like they do for existing brew-only
+ optional tools: unsupported tools are omitted from selection.
+
+Rollback is source-level: reintroducing pyenv shell blocks and
+`private_dot_local/bin/executable_pyenv-shell` in the chezmoi source, then
+applying dotfiles, restores the previous shell integration model assuming user
+pyenv state still exists.
+
+## Alternatives Considered
+
+| Alternative | Strengths | Why Rejected |
+|-------------|-----------|--------------|
+| Keep pyenv and add uv alongside it. | Maximum compatibility for bare `python` directory switching. | Preserves shell complexity for behavior the user does not use. |
+| Create a dedicated Python setup subsystem. | Could install uv, preinstall Python versions, and define a complete Python baseline. | Over-engineered for a repo with no Python project payload and no installer-time Python dependency. |
+| Add standalone uv installer fallback now. | Would support non-Homebrew active package managers even without native package mappings. | More installer design work than the immediate need justifies; most target setups use Homebrew. |
+| Add default-selected/recommended optional tools. | Could nudge users toward uv during setup. | Adds UX and installer complexity for a tool that should remain optional. |
+| Remove all Python completions. | Simplest shell cleanup. | `pip` remains core, Poetry remains common in existing projects, and installed pipx still benefits from accurate completions. |
+| Migrate existing pyenv/pipx/Poetry state. | Could produce a cleaner local machine after migration. | Outside installer responsibility and risks changing user-owned state unexpectedly. |
+
+## Risks And Tradeoffs
+
+| Risk / Tradeoff | Impact | Mitigation Or Acceptance |
+|-----------------|--------|--------------------------|
+| `uv` is initially Homebrew-only in optional tools. | Non-Homebrew active package managers will not offer uv through the installer. | Accepted for MVP; future standalone fallback can be designed if non-Homebrew setups become important. |
+| Removing pyenv shell integration may surprise projects that relied on bare `python` switching, `pyenv` on PATH, or pyenv activation from `.envrc`/`.python-version`. | Such projects may resolve a different Python or fail to call `pyenv` unless the user invokes uv, activates an environment, or manages pyenv separately. | Accepted because the user does not rely on this behavior; pyenv state is not deleted. |
+| Keeping Poetry/pip/pipx completion caching preserves some legacy Python surface. | Shell config remains slightly broader than a pure uv setup. | Accepted because completion generation is guarded and useful for existing projects or machines where pipx remains installed. |
+| Relying on Homebrew for uv/uvx completions ties completion availability to the brew formula. | If uv is installed outside Homebrew, uv/uvx completions may not be available from the dotfiles. | Accepted because the MVP installs uv through Homebrew only; non-Homebrew uv installation is future work. |
+| Installer-driven Homebrew installs can leave `~/.zcompdump` stale. | uv/uvx completion files may not be discovered immediately after installer-run `brew install uv`. | Accepted for MVP; the RFC narrows success to Homebrew-provided completion files being available on `fpath`, not immediate compinit cache refresh. |
+| No user-state cleanup leaves old pyenv/pipx files on disk. | Machines may contain unused legacy state. | Accepted because the installer is not a state keeper; cleanup can be manual or future explicit work. |
+
+## Success Criteria
+
+- `uv` is offered and resolvable as an optional tool on Homebrew-backed installs.
+- pyenv-specific shell startup behavior is removed from generated Zsh files.
+- Shell startup documentation no longer describes pyenv as part of the runtime
+ model.
+- `pip` and `poetry` completions are generated only when the corresponding
+ command exists and the cache is missing or stale.
+- `pipx` completions are generated only when both `pipx` and
+ `register-python-argcomplete` exist and the cache is missing or stale.
+- Brew-installed uv/uvx completion files are provided in Homebrew's zsh
+ completion directory and made discoverable through `fpath`, without
+ dotfiles-managed uv/uvx completion generation or installer-level zcompdump
+ invalidation.
+- Existing user state for pyenv, pipx, and Poetry is not modified by the
+ dotfiles or installer.
+
+## Future Work
+
+- Non-Homebrew uv installation can be revisited later, either through a
+ generalized optional-tool alternate-install mechanism or a uv-specific
+ standalone fallback. That decision is intentionally outside this RFC and must
+ include a completion-source decision for uv/uvx.
+- Installer-level zcompdump invalidation after optional tool installation can be
+ considered separately if completion freshness after package-manager installs
+ becomes important.
+
+## Planning Handoff
+
+Planning should preserve the MVP boundary. The design is not a request for a
+general Python management system, optional-tool recommendation UX, state
+migration, or standalone installer support. Any implementation plan should keep
+changes within the existing optional-tools mapping model, shell templates,
+pyenv-specific source files, and documentation that currently describes shell
+startup behavior.
+
+If future planning proposes non-Homebrew uv installation, it should be treated
+as a separate design extension because it changes installer installation methods
+and security considerations.
+
+## Source References
+
+| Source | What It Confirms |
+|--------|------------------|
+| `docs/domain.md` | Optional tools are daily-use CLI tools, are not persisted in chezmoi data, and may have platform-dependent availability. |
+| `docs/architecture.md` | The project separates installer bootstrap, chezmoi templates, and shell runtime behavior. |
+| `docs/processes/tools-installation.md` | Optional tools are pre-filtered through package resolution, selected interactively or via `--install-tools`, installed through the active package manager, and non-fatal. |
+| `docs/processes/shell-startup.md` | Current documented shell startup includes pyenv setup, lazy pyenv initialization, and completion caching for Poetry, pip, and pipx. |
+| `dot_zshenv.tmpl` | Current all-shell startup adds pyenv shims and pyenv binary path when `~/.pyenv` exists. |
+| `dot_zshrc.tmpl` | Current interactive startup lazily initializes pyenv and caches Poetry, pip, and pipx completions. |
+| `private_dot_local/bin/executable_pyenv-shell` | Current repo includes a pyenv-specific workaround shim. |
+| `installer/internal/config/tools.yaml` | Current optional tool list does not include uv. |
+| `installer/internal/config/packagemap.yaml` | Current package map has existing brew-only tools and no uv mapping. |
+| `installer/cmd/install.go` | Current optional-tools flow filters resolvable tools before prompt/install and installs through `ToolsInstaller`. |
+| `installer/lib/toolsinstaller/installer.go` | Current `ToolsInstaller` resolves each tool and installs through the package manager, continuing after failures. |
+| uv documentation: `https://docs.astral.sh/uv/concepts/python-versions/` | uv supports managed Python versions, `.python-version`, automatic downloads, and system Python discovery. |
+| uv documentation: `https://docs.astral.sh/uv/concepts/tools/` | uv provides `uv tool install` and `uvx` for isolated Python CLI tools. |
+| uv documentation: `https://docs.astral.sh/uv/getting-started/installation/` | uv is available through Homebrew and other install paths, including a standalone installer. |
+| Homebrew uv formula fetched via `gh api repos/Homebrew/homebrew-core/contents/Formula/u/uv.rb` | Homebrew generates completions from both `uv generate-shell-completion` and `uvx --generate-shell-completion` during formula installation. |
+| `dot_zshrc.tmpl` | Homebrew's zsh `site-functions` directory is added to `fpath` before `compinit`, allowing brew-installed completions to be discovered. |
+| Settled user decision | Directory-sensitive bare `python` switching is not important in day-to-day use. |
+| Settled user decision | A full Python setup subsystem, preinstalled Python versions, and user-state migration are out of scope. |
+| Settled user decision | `pip`, `poetry`, and guarded `pipx` completions should remain. |
+| Settled user decision | `uv` should not be preselected or specially recommended in the optional-tools prompt. |
+| Settled user decision | Brew-only optional-tool support is acceptable for the MVP because most target setups use Homebrew. |
diff --git a/docs/rfcs/reviews/RFC-uv.rfc-architect-reviewer.md b/docs/rfcs/reviews/RFC-uv.rfc-architect-reviewer.md
new file mode 100644
index 0000000..e369221
--- /dev/null
+++ b/docs/rfcs/reviews/RFC-uv.rfc-architect-reviewer.md
@@ -0,0 +1,22 @@
+# RFC Architecture Review: RFC-0001 Switch To uv For Python Tooling
+
+## Verdict
+
+PASS
+
+## Critical Findings
+
+None.
+
+## Concerns
+
+None.
+
+## Observations
+
+- The main architectural boundaries remain sound: uv is a normal optional tool; no Python setup subsystem, new chezmoi data contract, standalone installer fallback, or user-state migration is introduced.
+- R4 resolves the prior blocking finding about Homebrew-owned completions and `compinit -C` cache semantics. The RFC now explicitly states that stale `~/.zcompdump` may delay discovery of Homebrew-provided `_uv` and `_uvx`, and that installer-level cache invalidation is out of scope for this MVP.
+- R4's completion ownership split is architecturally coherent: pip, Poetry, and pipx remain dotfiles-managed guarded cache targets, while uv/uvx completions are owned by Homebrew for the brew-only MVP.
+- The pipx completion contract now covers both required executables: `pipx` and `register-python-argcomplete`.
+- Current-state claims checked against source remain broadly consistent: pyenv PATH setup exists in `dot_zshenv.tmpl`, lazy pyenv initialization and pip/Poetry/pipx completion caching exist in `dot_zshrc.tmpl`, `pyenv-shell` exists as a local shim, optional tools are pre-filtered through package resolution, and `uv` is not currently in `tools.yaml` or `packagemap.yaml`.
+- The active package-manager wording concern from the prior review is resolved; R4 consistently describes unsupported uv availability as non-Homebrew active package-manager behavior rather than OS-level Linux behavior.
diff --git a/docs/rfcs/reviews/RFC-uv.rfc-clarity-reviewer.md b/docs/rfcs/reviews/RFC-uv.rfc-clarity-reviewer.md
new file mode 100644
index 0000000..1c3508b
--- /dev/null
+++ b/docs/rfcs/reviews/RFC-uv.rfc-clarity-reviewer.md
@@ -0,0 +1,35 @@
+# RFC Clarity Review: RFC-0001 Switch To uv For Python Tooling
+
+## Verdict
+
+PASS
+
+## Critical Findings
+
+Empty.
+
+## Concerns
+
+Empty.
+
+## Observations
+
+- R4 keeps the MVP boundary explicit: uv is a normal optional tool, Homebrew-only
+ availability is accepted for this RFC, standalone fallback is future work, no
+ user-state migration is included, and installer-level zcompdump invalidation is
+ out of scope.
+- R4 names `docs/domain.md`, `docs/architecture.md`, and
+ `docs/processes/shell-startup.md` as documentation updates needed to keep the
+ optional-tool and shell-startup descriptions consistent with the chosen model.
+- The pipx role is clear: pipx is retained only as a guarded completion target
+ when both `pipx` and `register-python-argcomplete` are installed, while uv is
+ the preferred Python tooling entrypoint and pipx is not the preferred Python
+ tool manager.
+- The completion-source distinction is clear: `pip`, `poetry`, and `pipx` keep
+ guarded dotfiles-managed cache generation, while uv/uvx completions are not
+ generated by the dotfiles and instead come from Homebrew's zsh
+ `site-functions` directory for brew-installed uv.
+- R4 explicitly scopes the stale `~/.zcompdump` behavior: Homebrew may install
+ `_uv` and `_uvx`, but `compinit -C` can delay discovery until the completion
+ cache refreshes; this is accepted rather than left as an unresolved follow-up
+ inside the RFC.
diff --git a/docs/rfcs/reviews/RFC-uv.rfc-risk-reviewer.md b/docs/rfcs/reviews/RFC-uv.rfc-risk-reviewer.md
new file mode 100644
index 0000000..b42e46c
--- /dev/null
+++ b/docs/rfcs/reviews/RFC-uv.rfc-risk-reviewer.md
@@ -0,0 +1,23 @@
+# RFC Risk Review: RFC-0001 Switch To uv For Python Tooling
+
+## Verdict
+
+PASS
+
+## Critical Findings
+
+Empty.
+
+## Concerns
+
+Empty.
+
+## Observations
+
+- R4 resolves the prior stale `~/.zcompdump` concern at the design level. The RFC now explicitly states that `compinit -C` may reuse an existing completion dump, that installer-driven Homebrew installs do not gain a new invalidation path, and that immediate uv/uvx completion discovery is outside the MVP success boundary.
+- R4 resolves the prior pipx completion guard concern. The completion contract, control flow, data/state section, compatibility section, and success criteria now require both `pipx` and `register-python-argcomplete` before refreshing `_pipx`.
+- The uv/uvx completion-generation scope remains appropriately narrow: rely on Homebrew's uv formula and existing Homebrew `fpath` loading rather than adding dotfiles-managed uv/uvx cache files.
+- The pyenv removal boundary remains clear: no shim PATH setup, no `~/.pyenv/bin` PATH setup, no lazy initialization for `.python-version`/`.envrc`, and no `pyenv-shell` workaround.
+- The no-migration and residual-state behavior is explicit enough for planning: existing pyenv, pipx, Poetry, uv-managed state, and old completion-cache files may remain and are not treated as authoritative current dotfile state.
+- Brew-only, optional uv availability is acknowledged as an accepted MVP tradeoff; the future non-Homebrew uv path is correctly treated as a separate design extension with its own completion-source and security decisions.
+- Removing pyenv shell integration is a real compatibility break for projects that depended on bare `python` switching, but the RFC states this as an accepted user decision and preserves rollback at the source-template level.
diff --git a/dot_agents/skills/documenting-architecture/SKILL.md b/dot_agents/skills/documenting-architecture/SKILL.md
index b035233..1b82ef1 100644
--- a/dot_agents/skills/documenting-architecture/SKILL.md
+++ b/dot_agents/skills/documenting-architecture/SKILL.md
@@ -14,6 +14,7 @@ Document how a system is designed: its layers, boundaries, communication pattern
3. **Accurate to the Code**: Document the architecture as it IS, not as it was designed to be. If the code has drifted from the original vision, document reality.
4. **No Duplication Across Levels**: Architecture docs reference domain concepts — they never redefine business terms. If you need to mention a domain entity, link to the domain docs. Similarly, don't describe individual component internals — that belongs in component docs.
5. **Discover, Don't Assume**: Read the code to understand the actual architecture. Don't project patterns onto it based on naming alone.
+6. **Proportionality To Document Purpose**: A feature can require architecture doc updates without becoming the architecture's center of gravity. Preserve the target doc's existing abstraction level and emphasis. Mention feature-specific tools, libraries, or commands only where they change durable boundaries, dependencies, or decisions.
## Documentation Hierarchy
@@ -133,5 +134,6 @@ See `docs/architecture/.md` for .
- **Never describe component internals** — that belongs in component docs; architecture describes how components relate
- **Document reality, not aspirations** — if the code doesn't match the intended architecture, document what exists and note the drift
- **Rationale is mandatory** — every design decision must include "why", not just "what"
+- **Preserve proportional emphasis** — broad architecture docs should stay broad. If a feature only changes one dependency, guard, or integration point, update that specific claim instead of re-centering the document around the feature.
- **Use reference-style links** — when linking to other docs or source files, use reference links (`[text][ref]` with `[ref]: path` at the bottom of the file) rather than inline links. They read better in source and are easier to maintain.
- **Propose structure first** — if no architecture docs exist yet, propose a directory structure and format before creating files
diff --git a/dot_agents/skills/documenting-business-processes/SKILL.md b/dot_agents/skills/documenting-business-processes/SKILL.md
index 42016a5..cd55730 100644
--- a/dot_agents/skills/documenting-business-processes/SKILL.md
+++ b/dot_agents/skills/documenting-business-processes/SKILL.md
@@ -14,6 +14,7 @@ Document the business processes and workflows a system implements: how domain en
3. **NOT Development Processes**: This skill documents business workflows the system implements (user registration, order fulfillment). Development processes (how to test, deploy, contribute) belong in skills and contribution guidelines — not here.
4. **No Duplication Across Levels**: Reference domain docs for entity definitions and architecture docs for system structure. Process docs describe the FLOW — how entities traverse the architecture. Don't redefine domain terms or re-explain architectural patterns.
5. **Include Failure Paths**: Happy paths are easy. Document what happens when things go wrong — failed payments, validation errors, timeouts, partial completions.
+6. **Proportionality To Process Scope**: A feature can change one step of a process without becoming the whole process. Preserve the existing process's trigger, actors, and end-to-end emphasis. Mention feature-specific tools or mechanisms only where they affect the flow, decisions, outcomes, or failure handling.
## Documentation Hierarchy
@@ -163,6 +164,7 @@ See `docs/processes/.md` for .
- **Never redefine domain concepts or architectural patterns** — reference the appropriate docs
- **Always include failure paths** — happy-path-only docs are incomplete and misleading
- **Business language first** — describe what happens from the business perspective, then note which components are involved
+- **Preserve proportional emphasis** — if updating an existing broad process doc, adjust the affected steps and failure scenarios without turning the process into a feature-specific walkthrough.
- **Use reference-style links** — when linking to other docs or source files, use reference links (`[text][ref]` with `[ref]: path` at the bottom of the file) rather than inline links. They read better in source and are easier to maintain.
- **Decompose complex steps into sub-processes** — if a step has its own decision branches, failure modes, or multiple sequential actions, it needs its own doc. Don't inline what should be a sub-process.
- **Match existing sub-process patterns** — if a parent doc already has sub-process links, new sub-processes must follow the exact same structure and link style
diff --git a/dot_agents/skills/documenting-components/SKILL.md b/dot_agents/skills/documenting-components/SKILL.md
index 64d70a6..1297d34 100644
--- a/dot_agents/skills/documenting-components/SKILL.md
+++ b/dot_agents/skills/documenting-components/SKILL.md
@@ -15,6 +15,7 @@ Create focused, accurate documentation for specific components or areas of a cod
4. **Accurate Over Comprehensive**: Only document what you can verify from the code. Never invent or assume behavior.
5. **Discover, Don't Assume**: Find the project's existing documentation structure before creating new files.
6. **No Duplication Across Levels**: Before documenting a concept, check if it already exists at a higher documentation level (domain, architecture, or business processes). If it does, **reference it** instead of redefining it. Component docs are the lowest layer — they reference all layers above.
+7. **Proportionality To Component Scope**: Document the component's durable responsibilities, interfaces, and gotchas. Do not let a recent feature dominate the component doc unless it fundamentally changes the component's purpose or primary API.
## Documentation Hierarchy
@@ -111,5 +112,6 @@ After documentation is created, future planning sessions and executing agents be
- **Match existing doc style** — don't introduce a new format if docs already exist
- **Propose, don't force** — if unsure about structure, location, or scope, ask the user
- **Keep it maintainable** — shorter accurate docs beat comprehensive stale docs
+- **Preserve proportional emphasis** — when updating existing component docs for a feature, change the relevant section only. Avoid converting component documentation into a feature changelog.
- **Use reference-style links** — when linking to other docs or source files, use reference links (`[text][ref]` with `[ref]: path` at the bottom of the file) rather than inline links. They read better in source and are easier to maintain.
- **No meta-commentary** — don't add "this doc was auto-generated" or session timestamps
diff --git a/dot_agents/skills/documenting-domain/SKILL.md b/dot_agents/skills/documenting-domain/SKILL.md
index bceea9f..c2d9d14 100644
--- a/dot_agents/skills/documenting-domain/SKILL.md
+++ b/dot_agents/skills/documenting-domain/SKILL.md
@@ -14,6 +14,7 @@ Document the business domain of a project: its terminology, entities, relationsh
3. **Accurate Over Comprehensive**: Only document domain concepts that actually exist in the codebase. Don't invent domain models the project doesn't implement.
4. **Non-Technical Where Possible**: Domain docs should be readable by non-technical stakeholders. Minimize code references — save those for component docs.
5. **No Duplication Across Levels**: Domain docs are the canonical source for business concepts. Architecture, process, and component docs **reference** domain docs — they never redefine domain terms. If you find a concept documented elsewhere, consolidate it here and replace the duplicate with a reference.
+6. **Proportionality To Document Purpose**: A feature can motivate a doc update without becoming the doc's center of gravity. Preserve the document's existing purpose, audience, abstraction level, and relative emphasis. Mention feature-specific tools or mechanisms only as much as the domain concept requires.
## Documentation Hierarchy
@@ -111,5 +112,6 @@ See `docs/domain/.md` for .
- **One definition per concept** — if a term is already defined in domain docs, other layers must reference it, not redefine it
- **Defer process details to process docs** — if a concept involves a multi-step flow (loading chain, resolution sequence, initialization steps), define the concept here and link to the process doc for the "how"
- **No behavioral conditionals** — if you're writing "when X happens", "in Y mode", or "if Z flag is set", that's a process description. Domain docs define static properties of concepts (what they are, what they contain, how they relate). Conditional behavior, modes, flags, and runtime decisions belong in process docs.
+- **Preserve proportional emphasis** — if updating an existing broad domain doc for a narrow feature, make the smallest accurate change. Do not let the feature's terminology dominate the domain doc unless the feature actually changes the domain's primary language.
- **Use reference-style links** — when linking to other docs or source files, use reference links (`[text][ref]` with `[ref]: path` at the bottom of the file) rather than inline links. They read better in source and are easier to maintain.
- **Propose structure first** — if no domain docs exist yet, propose a directory structure and format to the user before creating files
diff --git a/dot_agents/skills/documenting-library-guides/SKILL.md b/dot_agents/skills/documenting-library-guides/SKILL.md
index c665d4c..a837e35 100644
--- a/dot_agents/skills/documenting-library-guides/SKILL.md
+++ b/dot_agents/skills/documenting-library-guides/SKILL.md
@@ -14,6 +14,7 @@ Create user-facing documentation for libraries — the docs users actually read.
3. **Connected to the Code**: Every example must come from the actual codebase — real types, real method signatures, real return values. Never write pseudocode or hypothetical examples. If the API changes, the docs should feel immediately stale so they get updated.
4. **Site-Ready Structure**: Organize docs as if they'll be served by a static site generator (Starlight, MkDocs, Docusaurus). Each page stands alone but fits a reading order. Sidebar-friendly hierarchy, clear page boundaries, cross-page linking.
5. **Adjacent, Not Redundant**: These docs complement inline code documentation — they don't replace it. Inline docs describe the API surface; library guides describe how to *use* it to get things done. Never duplicate what a godoc/rustdoc/typedoc already provides.
+6. **Proportionality To Reader Journey**: A new feature can update guide examples without becoming the whole guide. Preserve each page's original reader goal and level of detail unless the feature changes that goal.
## Documentation Structure
@@ -104,3 +105,4 @@ After writing:
- **Keep getting-started ruthlessly short** — the reader's patience is at its lowest here; get them to "it works" fast
- **Use reference-style links** — when linking between pages or to source files, use reference links for readability and maintainability
- **Match the library's terminology** — use the same names the API uses, don't invent synonyms
+- **Preserve proportional emphasis** — update feature-relevant examples and explanations without turning broad guides into release notes or single-feature walkthroughs.
diff --git a/dot_agents/skills/executing-plans/SKILL.md b/dot_agents/skills/executing-plans/SKILL.md
index 25dd141..f0c2ca5 100644
--- a/dot_agents/skills/executing-plans/SKILL.md
+++ b/dot_agents/skills/executing-plans/SKILL.md
@@ -31,6 +31,7 @@ Do not load or mix instructions from the other runtime adapter in the same turn.
2. **Progress Is Always Persisted**: After every meaningful step, update the progress file. If the session drops, the executor resumes from the last checkpoint — not from scratch.
3. **Tests Are Immutable to the Implementer**: The implementer cannot modify tests. If it believes a test is wrong, it reports this and moves on. Disputes are batched for human resolution.
4. **Independent Work Continues**: When a task is blocked (test dispute, failure), the executor continues with independent tasks.
+5. **Execution Bindings Are Correctness, Not Optimization**: When a plan assigns worker bindings or model tiers, executing through those bindings is mandatory. The coordinator does not silently self-execute implementation work just because it can edit files.
## Workflow
@@ -61,11 +62,22 @@ Check for an existing progress file alongside the plan (`progress.md` in the pla
The progress file is the source of truth for task-by-task execution status, tests, blockers, disputes, and completion. If an anchor is active, update it only for feature-level context: new durable decisions, changed constraints, spec/plan deviations, unresolved questions, or handoff state. Do not duplicate progress tables or per-task status in the anchor.
-### Step 3: Execute Tasks
+### Step 3: Execution Preflight
+
+Before editing implementation files, verify the execution mechanics and record them in progress.
+
+1. **Worker binding audit**: For every sub-plan, identify the planned implementer worker, test author worker, model tier, and runtime dispatch mechanism. If the plan has two or more sub-plans, or if any sub-plan has an explicit model tier, the coordinator must dispatch through the assigned execution binding. Coordinator self-execution is allowed only for progress files, coordination artifacts, or a single trivial sub-plan with no explicit binding requirement.
+2. **Binding availability check**: Use the active runtime adapter to verify every assigned worker is discoverable and invokable before executing any sub-plan. If a binding is missing or cannot be invoked, diagnose and retry once when the cause is mechanical (for example, stale discovery or permission shape). If it still cannot be invoked, stop and ask the user. Do not fall back to the coordinator or a more expensive model.
+3. **TDD isolation check**: For each task with testable acceptance criteria, verify whether the active runtime can route the test author into an isolated workspace. If the runtime adapter provides an isolation path, attempt or otherwise concretely verify that path before skipping structural TDD. If verification fails, record the attempted mechanism and stop to ask whether to fix isolation or explicitly skip structural TDD. Do not record a generic "runtime cannot provide isolated workspace" reason while an untried runtime-specific isolation path exists.
+4. **Progress audit update**: Add or update the progress file's execution audit with planned worker, actual worker, model/effort, dispatch evidence, and TDD gate status for each task.
+
+Only proceed once the audit is complete or the user explicitly authorizes a deviation.
+
+### Step 4: Execute Tasks
For each task in execution order (respecting dependencies):
-#### 3a. Test Authoring
+#### 4a. Test Authoring
**When to skip (no testable work)**: Some tasks don't have testable work — documentation updates, file moves, configuration changes, or tasks with no acceptance criteria. Skip test authoring for these and proceed directly to implementation.
@@ -82,11 +94,11 @@ For each task in execution order (respecting dependencies):
If the code surface isn't ready for TDD, skip test authoring and proceed directly to implementation without structural separation. Record the decision briefly in the progress file (Tests column: `skipped`, Notes: e.g., "declared untestable in AGENTS.md" or "no testable seams"). The implementer still receives the full task with acceptance criteria — it just doesn't receive pre-written tests and isn't bound by the test immutability constraint.
-**Isolation capability gate**: Before structural TDD, use the active runtime adapter to verify that the runtime can place the test author in an isolated workspace that does not contain the planning artifacts. If the runtime cannot enforce that isolation, skip structural TDD and proceed directly to implementation. Record the decision briefly in the progress file (Tests column: `skipped`, Notes: e.g., "runtime cannot provide isolated test-author workspace").
+**Isolation capability gate**: Before structural TDD, use the active runtime adapter to verify that the runtime can place the test author in an isolated workspace that does not contain the planning artifacts. If the runtime has no enforceable isolation path, skip structural TDD and proceed directly to implementation. If the adapter names an isolation path but verification fails, stop and ask whether to fix isolation or explicitly skip structural TDD. Record the decision briefly in the progress file (Tests column: `skipped`, Notes: e.g., "no runtime isolation mechanism" or "user approved TDD skip after failed `` dispatch").
**Compilation readiness gate**: Before spawning the test author, verify that the target package compiles at the current execution state and that the required test infrastructure already exists. Earlier sub-plans may have changed interfaces or compile-time assertions in ways that leave the package temporarily uncompilable even though the task is still meant to follow structural TDD. Check for missing or stale mocks, fixtures, and test helpers as well. If the project uses generated mocks, confirm that the mock for the dependency under test exists and is up to date.
-If either check fails, resolve the blocker within the TDD framework instead of skipping TDD or inverting the order. Acceptable scaffolding includes adding method stubs that panic or return zero values to satisfy interface assertions, adding the package to the mock generator configuration and regenerating mocks, or creating missing test helpers. These are temporary unblockers for the test author, not the task implementation itself. Record every scaffold created in the progress file so the implementer knows what must be replaced in step 3b.
+If either check fails, resolve the blocker within the TDD framework instead of skipping TDD or inverting the order. Acceptable scaffolding includes adding method stubs that panic or return zero values to satisfy interface assertions, adding the package to the mock generator configuration and regenerating mocks, or creating missing test helpers. These are temporary unblockers for the test author, not the task implementation itself. Record every scaffold created in the progress file so the implementer knows what must be replaced in step 4b.
**Isolation via isolated workspace**: The test author must NOT have access to plan files. Use the active runtime adapter's isolation mechanism to create a temporary isolated workspace containing the relevant code surface but not the planning artifacts.
@@ -115,15 +127,15 @@ The test author writes tests grounded in the acceptance criteria and confirms th
**Update progress**: Record test authoring as complete, note test file paths.
-#### 3b. Implementation
+#### 4b. Implementation
-**Without structural TDD** (test authoring was skipped due to testability): Spawn an implementer sub-agent with the complete task. No pre-written tests exist, so the immutability constraint doesn't apply. The implementer implements against the acceptance criteria directly. It returns implementation status and files created/modified. Existing tests must still pass — regressions are still caught in step 3c.
+**Without structural TDD** (test authoring was skipped due to testability): Spawn an implementer sub-agent with the complete task. No pre-written tests exist, so the immutability constraint doesn't apply. The implementer implements against the acceptance criteria directly. It returns implementation status and files created/modified. Existing tests must still pass — regressions are still caught in step 4c.
-**With structural TDD** (tests were written in 3a): Spawn an **implementer** sub-agent with full context:
+**With structural TDD** (tests were written in 4a): Spawn an **implementer** sub-agent with full context:
**What the implementer receives:**
- The complete task (all sections — design decisions, context, contracts, acceptance criteria)
-- The tests written in step 3a (file paths)
+- The tests written in step 4a (file paths)
- The project's required skills (if the plan specifies them for this task, or via the implementer's execution binding)
- Any outputs from prerequisite tasks (relayed by the executor)
@@ -141,7 +153,7 @@ The implementer implements the task and runs tests. It returns:
**Update progress**: Record implementation status, note created files, record any disputes.
-#### 3c. Handle Results
+#### 4c. Handle Results
**With structural TDD:**
@@ -155,7 +167,7 @@ The implementer implements the task and runs tests. It returns:
- **Implementation complete, no regressions**: Mark task as `done`. Proceed to the next task.
- **Existing tests regress**: Mark as `blocked: regression`. Same treatment as above — the implementation broke something outside its scope.
-### Step 4: Resolve Blocks
+### Step 5: Resolve Blocks
When the executor reaches a natural breakpoint — all independent work is done, or all remaining tasks depend on a blocked one — present all blocked items to the user at once:
@@ -170,7 +182,7 @@ When the executor reaches a natural breakpoint — all independent work is done,
The user resolves each item (fix the test, fix the AC, adjust the task, or accept as-is). The executor then re-runs the affected tasks from the appropriate step (test authoring if AC changed, implementation if tests changed).
-### Step 5: Completion
+### Step 6: Completion
When all tasks are `done`:
@@ -198,13 +210,14 @@ If the plan specifies runtime-specific execution bindings, the executor uses the
For tasks without testable AC (docs, config, file moves), only the implementer binding is needed.
-If no execution bindings are specified, the executor spawns sub-agents with the runtime's default model and tool configuration. The structural isolation requirements and prompt-hygiene rules still apply regardless, but agents may not have skills preloaded.
+If no execution bindings are specified, the executor may use the runtime's default sub-agent setup only for a single-sub-plan plan with no explicit model tier. For multi-sub-plan plans or plans with explicit model assignments, missing bindings are a blocker that must be resolved before implementation starts.
## Rules
- **Never let the test author see design decisions** — the structural separation is the entire point. If the test author's prompt accidentally includes plan context, the separation is broken.
-- **Never claim structural TDD without enforced isolation** — if the active runtime cannot place the test author in the required isolated workspace, skip structural TDD and record the reason. Prompt hygiene alone does not satisfy the physical isolation requirement.
+- **Never claim structural TDD without enforced isolation** — if the active runtime cannot place the test author in the required isolated workspace, skip structural TDD only after the runtime-specific isolation path is verified unavailable or the user explicitly approves the skip. Prompt hygiene alone does not satisfy the physical isolation requirement.
- **Never let the implementer modify tests** — disputes are recorded and batched, not resolved by the implementer.
+- **Never self-execute assigned worker tasks** — if a task has an assigned worker or model tier, dispatch it through the runtime binding. If dispatch fails, diagnose and retry once, then stop and ask the user rather than doing the task in the coordinator context.
- **Always update progress after each step** — this is the checkpoint mechanism. If you skip an update and the session drops, work is lost.
- **Do not use anchors as progress files** — anchors preserve feature-level rationale and handoff context. Progress files preserve mechanical execution state.
- **Continue independent work when blocked** — don't stop the entire execution because one task has a dispute. If the plan specifies dependencies, use them to determine what can proceed. If no dependencies are specified, treat remaining tasks as sequential and pause at the blocked one.
diff --git a/dot_agents/skills/executing-plans/assets/progress-template.md b/dot_agents/skills/executing-plans/assets/progress-template.md
index 9b7c0fd..bcad263 100644
--- a/dot_agents/skills/executing-plans/assets/progress-template.md
+++ b/dot_agents/skills/executing-plans/assets/progress-template.md
@@ -24,6 +24,12 @@ The progress file is the checkpoint mechanism. It must be updated after every me
## Current State
+## Execution Audit
+
+| Task | Planned Worker | Actual Worker | Model / Effort | Dispatch Evidence | TDD Gate |
+|------|----------------|---------------|----------------|-------------------|----------|
+| | | | | | |
+
## Test Artifacts