ADR-0013: Adoption version record and drift warnings
- Status: Accepted
- Date: 2026-06-21
- Deciders: Michel Gillet
Context
A2C consumer repositories adopt a specific workflow version through a2c init or a2c bootstrap. Human-facing adoption is recorded in ADR-0000 (version, delivery mode, mount path). That ADR is the architectural decision log entry; it is not a machine-checkable contract for everyday CLI use.
Without a tool-internal adoption anchor:
- Upgrading the installed
a2cCLI does not surface that the repository was adopted with an older version. a2c bootstrap --with-ai-rules submodule|clonecan leavetools/ai-rules/on the method repository default branch instead of the tag matching the adopting CLI.- Copy delivery has no durable record of which method version the copied
rules/,prompts/, and related assets represent.
Operators and AI agents need visible, repeatable signals when tool version, recorded adoption, and installed method assets diverge — without blocking routine work on the first detection.
This ADR complements the consumer ADR-0000 convention described in docs/adr/README.md and bootstrap mount behavior introduced in release 0.5.0.
Decision
1. Machine-readable adoption record
On the first successful a2c init or a2c bootstrap, A2C writes .a2c/adoption.yaml (schema version 1).
| Field | Semantics |
|---|---|
tool_version | A2C CLI version at first adoption — frozen on first write; never overwritten |
recorded_at | ISO-8601 UTC timestamp of first write |
first_command | init or bootstrap — which command created the file |
delivery | none, copy, submodule, or clone — updated when a2c bootstrap runs |
method_ref | Expected method version: git tag or commit for mount modes; vX.Y.Z for copy |
method_repo_url | Source URL when delivery is submodule or clone |
When a2c bootstrap runs after a prior a2c init, it updates delivery, method_ref, and method_repo_url but does not change tool_version or first_command. When bootstrap runs alone (including its internal init), first_command is bootstrap.
The file lives under .a2c/ alongside .a2c/config.yaml — tool-internal, not a human-facing planning artifact.
2. Drift warnings on every command
Every a2c command (except init, bootstrap, and version) compares:
- Adopted CLI vs running CLI —
tool_versionin.a2c/adoption.yamlvsa2c_core.__version__ - Installed method vs recorded method — for a git checkout at
tools/ai-rules/, resolved tag or commit vsmethod_ref - Installed method vs current CLI — mounted ref vs expected
v{current CLI version} - Copy delivery — recorded
method_refvs expectedv{current CLI version}when no git mount is present
Mismatches emit warnings on stderr. They do not fail the command. Rationale: version drift is common during upgrades; operators should see it immediately but can still inspect, plan, or run read-only commands.
3. Bootstrap mount pinning
For --with-ai-rules submodule|clone, after clone or submodule init A2C checks out tag v{CLI version} at tools/ai-rules/ when that ref exists. The resolved ref is stored in method_ref. If checkout fails, bootstrap continues with a warning and records the HEAD ref actually present.
4. Doctor and legacy repositories
a2c doctorreports adoption record presence, mount ref when applicable, and a version alignment check. Missing adoption on pre-existing repositories is informational, not a hard doctor failure.- Repositories without
.a2c/adoption.yamlemit no drift warnings until init or bootstrap creates the file.
5. Relationship to consumer ADR-0000
| Artifact | Role |
|---|---|
docs/adr/0000-adopt-a2c-workflow.md (consumer) | Human architectural record of the adoption decision |
.a2c/adoption.yaml | Machine-readable adoption anchor for CLI drift detection |
docs/workflow/adoption.md (bootstrap) | Operator-facing notes generated at bootstrap time |
These three are consistent but serve different audiences. Changing adoption semantics requires a new superseding ADR, not silent edits to this one.
Consequences
Positive
- Operators and AI agents see version drift on every command without waiting for
a2c doctor. - Submodule and clone delivery pin to the adopting CLI tag by default, aligning method assets with the tool that performed bootstrap.
- Copy delivery records the expected method version even when no git mount exists.
- Legacy repositories without an adoption file continue to work; adoption can be established on next init or bootstrap.
Negative
- First-command-frozen
tool_versionmeans a repo init'd at 0.4.0 and bootstrapped later at 0.5.0 still reports 0.4.0 as the adopted tool version until manually reconciled (future tooling may offer explicit re-adoption). - Warnings-only policy may be ignored; a future ADR may escalate selected mismatches to errors.
- Repositories adopted before this ADR need a one-time init/bootstrap (or manual file creation) to gain drift detection.
References
- docs/adr/README.md — consumer ADR-0000 convention
- docs/cli.md — init, bootstrap, and warning behavior
- ADR-0000 — canonical method repository vs consumer adoption
- ADR-0005 — product boundaries and bootstrap assets
a2c_core.schemas.adoption.AdoptionRecord— schema version 1.a2c/adoption.yaml— path constantADOPTION_FILEina2c_core.contracts.paths