| CONTRIBUTING.md build commands were DEAD before PR #2871 | CONTRIBUTING.md:155 said build/Generate-Agents.ps1 PowerShell invocation until PR #2871 repointed it to build/generate_agents.py; zero .ps1 files exist in the repo (ADR-042) | Real commands: uv run python build/generate_agents.py and uv run python build/scripts/build_all.py |
| PEP 668: bare pip fails | pip install X errors with externally-managed-environment on uv-managed interpreters | Everything goes through uv: uv sync, uv add, uv run (scripts/bootstrap-vm.sh:118-123) |
| Skill scripts need the project venv | .claude/skills/github/scripts/pr/*.py import github_core, which imports yaml at load; bare python3 throws ModuleNotFoundError: No module named 'yaml' unless .venv/bin is first on PATH (bootstrap-vm.sh arranges that; a manual setup usually does not) | Run skill scripts with uv run python, which resolves the venv deterministically |
| Moving a worktree leaves the uv shebangs stale | Direct .venv/bin/pytest fails with "bad interpreter" after mv; the shebangs in .venv/bin/* (POSIX) or .venv/Scripts/* (Windows) still name the old worktree path (issue #3170) | Run scripts/maintenance/repair_worktree_venv.py with uv run python (or uv sync --frozen --extra dev --reinstall: --reinstall recreates the launchers a bare --frozen sync would leave stale, --extra dev keeps pytest/ruff/mypy, --frozen matches CI); prefer uv run python -m pytest for move-safe validation |
| Two floors, not one | pyproject.toml project.requires-python says requires-python = ">=3.14" (the dev/install contract), but plugin hooks run under the host's ambient interpreter, which may be older | Develop and test against .python-version (3.14.6). The blocking CI syntax gate parses every file at the hook-portability floor (3.10), NOT 3.14, so hooks stay portable to older hosts (issue #2655, decoupled from requires-python in issue #3008); see ai-agents-debugging-playbook |
| LF line endings enforced | CRLF in YAML frontmatter breaks the Copilot CLI parser (github/copilot-cli#694); .gitattributes:59 sets * text=auto eol=lf | Configure your editor for LF; never commit CRLF |
| Pre-push jobs can take minutes | Lefthook runs the named validators in lefthook.yml for matching push files | Budget minutes per push; do not attempt --no-verify (prohibited, AGENTS.md Never list) |
| Skill tests not collected by default | uv run pytest tests/ -x skips .claude/skills/*/tests/ (pyproject testpaths are tests, test) | Run skill tests explicitly: uv run pytest .claude/skills/NAME/tests/; details in ai-agents-validation-and-qa |