ADR-0015: Bootstrap dev environment and pre-commit hooks
- Status: Accepted
- Date: 2026-06-21
- Deciders: Michel Gillet
Context
A2C-governed repositories must version shared pre-commit configuration (ADR-0001) and include mandatory a2c-pre-commit-hooks with check-changelog (ADR-0003). The method repository a2c-workflow dogfoods a fuller baseline: file-hygiene hooks, tab removal for Markdown/YAML, and gitlint on the commit-msg stage — installed locally via scripts/setup-dev.sh / scripts/setup-dev.ps1 after editable install and pre-commit install.
Until this ADR, a2c bootstrap for consumer repositories only scaffolded a minimal .pre-commit-config.yaml containing check-changelog. Operators still had to:
- Manually extend the config with standard hygiene hooks and gitlint
pip install pre-commit(often globally or ad hoc)- Run
pre-commit installandpre-commit install --hook-type commit-msg
That gap caused “hooks not installed”, “gitlint missing”, and inconsistent rails across newly adopted repos — especially for teams that expect a2c bootstrap to be a one-shot adoption step comparable to superbuild / method-repo onboarding.
Consumer repositories are not always Python products, but pre-commit and gitlint run in isolated hook environments; they only require a host Python interpreter to bootstrap a local .venv/ for the hook manager.
Decision
1. Standard consumer .pre-commit-config.yaml
a2c bootstrap writes a stack-agnostic .pre-commit-config.yaml aligned with the method repository baseline:
| Block | Purpose |
|---|---|
a2c-pre-commit-hooks @ tag | check-changelog, check-web-sources |
pre-commit-hooks | case/merge conflict, YAML, EOF, mixed line endings, trailing whitespace |
Lucas-C/pre-commit-hooks | remove-tabs on *.md, *.mdc, *.yaml |
gitlint | Conventional Commits on commit-msg stage |
Ruff and other language-specific linters remain stack hooks — add via profiles or project ADRs, not the default bootstrap template.
Pin a2c-pre-commit-hooks by release tag (currently v0.3.0, same as method repo).
2. Automatic dev environment setup during bootstrap
After scaffolding config files, a2c bootstrap runs setup_dev_environment() (a2c_core.services.dev_setup):
.venv/— create at repository root when no activeVIRTUAL_ENVand no existing.venv/pip install pre-commit>=4.0into that venv (or active venv when bootstrap runs inside one)pre-commit installandpre-commit install --hook-type commit-msgwhen.git/exists
Failures are warnings, not bootstrap hard failures — adoption still completes when Python is missing, venv creation fails, or the target is not yet a git repository.
3. Re-run scripts and gitignore
Bootstrap also scaffolds:
| Artifact | Role |
|---|---|
.gitignore | Ignores .venv/ (and common editor noise) |
scripts/setup-dev.sh | Re-run venv + hook install (Unix / Git Bash) |
scripts/setup-dev.ps1 | Re-run venv + hook install (Windows) |
Clone workflows re-run scripts/setup-dev instead of remembering pip/pre-commit commands.
4. Relationship to method repository
| Context | Setup path |
|---|---|
a2c-workflow (method repo) | scripts/setup-dev.* + editable product install — unchanged |
| Consumer repo | a2c bootstrap auto-setup + scripts/setup-dev.* for re-runs |
Consumer bootstrap does not install a2c-core editable unless the project is a Python product that chooses to do so separately.
5. Prerequisites and limits
- Python 3.11+ on PATH (or active venv) for automatic hook install
- Git repository for hook registration —
git initbefore bootstrap, or runscripts/setup-devafter init - Hook environments download on first commit (pre-commit default); bootstrap only registers hooks
- Private
a2c-pre-commit-hooksaccess follows the same GitLab auth model as CI (ADR-0003)
Consequences
Positive
- One-shot
a2c bootstrapdelivers the same pre-commit baseline operators expect from the method repo - gitlint is present by default — no separate install step
- Local
.venv/isolates pre-commit from system Python scripts/setup-devgives a documented recovery path after clone
Negative
- Bootstrap requires network for
pip install pre-commitand later for first hook env creation - Non-git directories get config but not registered hooks until
git init+scripts/setup-dev - Repositories bootstrapped before this ADR need a one-time config refresh and
scripts/setup-dev(or re-bootstrap of config files) - Stack-specific hooks (Ruff, mypy) are still the project’s responsibility
References
- docs/cli.md — bootstrap behavior
- docs/workflow/reuse.md — adoption steps
- docs/workflow/pre-commit-policy.md — changed-file scope
- docs/workflow/a2c-pre-commit-hooks.md — mandatory hooks
- ADR-0001 — shared pre-commit policy
- ADR-0003 —
a2c-pre-commit-hooks a2c-workflow/.pre-commit-config.yaml— method repository baselinea2c_core.services.dev_setup— venv + hook install implementation