ADR-0024: Tool state root, write contract, and version migration
- Status: Accepted
- Date: 2026-07-25
- Deciders: Michel Gillet
Context
ADR-0013 introduced
.a2c/adoption.yaml, drift warnings, and method delivery via
copy / submodule / clone at tools/ai-rules/. Related ADRs hard-coded
the same .a2c/ prefix for config.yaml, cli-journal.yaml, and
migration.yaml (ADR-0014,
ADR-0016,
ADR-0017,
ADR-0018).
That approach has three problems:
- No abstract folder concept — changing the on-disk root requires amending every file ADR instead of one path-binding ADR.
- Write contract vs session pin — in superbuilds, many product repos share
one checkout while each repo’s adopted A2C version is the write contract.
Mounting a single
tools/ai-rules(or using the workspace superbuildtools/ai-rules) does not match per-repo authorship rules. Additive minors must not cause agents to emit newer-only artifacts while the repo’s adopted version is older. - Delivery — method assets for several write-contract versions must be
installable side by side (package / Conan / pip) under a local tree, without
committing full method trees into the superbuild or colliding with
superbuild-workflow at
$WORKSPACE/tools/ai-rules/.
Legacy repos still have .a2c/* and often $R/tools/ai-rules/ as the A2C method
mount. New repos should use .tools/esys/a2c/ for committed tool state and
.tools_local/esys/a2c/<version>/ for installed method assets.
Decision
1. Abstract locations (single binding ADR)
| Concept | Meaning |
|---|---|
| Tool state root | Committed A2C tool-internal state for one git repository |
| Method asset root | On-disk tree of method assets (rules/, prompts/, templates/, …) for a specific write-contract version |
Concrete bindings (this ADR):
| Concept | Legacy (read if new absent) | Canonical for new repos / new layout versions |
|---|---|---|
| Tool state root | .a2c/ | .tools/esys/a2c/ |
| Method asset root (installed) | $R/tools/ai-rules/ when that tree is an A2C method checkout | .tools_local/esys/a2c/<version>/ (gitignored install prefix) |
Future path changes amend or supersede this ADR only. Other ADRs refer to
{tool_state_root}/… and “resolved method asset root for version V”, not to a
hard-coded folder string (except historical text in Superseded ADRs).
Files under tool state root include at least:
adoption.yamlconfig.yamlcli-journal.yamlmigration.yaml(when brownfield migration is in use)
2. Write contract
The repository’s adopted A2C version (consumer ADR-0000 + adoption record
tool_version / method_ref) is the write contract: durable A2C artifacts
(ADRs, ASRs, tool state, method-governed scaffolding) must be authored under that
version’s method rules.
- A workspace / session pin (e.g. newer CLI or superbuild-installed tools) may mount a newer method tree for reading; it must not silently apply newer-only write rules while the write contract is older.
- The repository has one write contract (its adopted version). Whether a parent workspace pins a newer A2C for its own session is outside that contract.
3. Method asset resolution (agents and CLI)
For A2C work in git repo R with write contract version V:
$WORKSPACE/.tools_local/esys/a2c/V/if present (superbuild shared install)- Else
$R/.tools_local/esys/a2c/V/if present (single-repo install) - Else
$R/tools/ai-rules/if present and recognized as an A2C method tree (legacy delivery) - Else fail / warn: install method assets for
V— do not invent rules
Never use $WORKSPACE/tools/ai-rules/ as the A2C method asset root. In a
superbuild that path is superbuild-workflow, not A2C.
4. Adoption record and delivery modes
Keep the machine-readable adoption record and drift-warning intent of ADR-0013.
- Path:
{tool_state_root}/adoption.yaml(legacy.a2c/adoption.yamlstill read when the new path is absent). - New repos after this ADR’s layout is required: write only under
.tools/esys/a2c/. - Extend
deliveryto include at least:none,copy,submodule,clone, andpackage(or equivalent) meaning method assets installed under.tools_local/esys/a2c/<version>/(PyPI, Conan, or other install). - Drift checks compare running CLI / recorded adoption / resolved method asset
root for V, not only a git checkout at
tools/ai-rules/.
Schema version may bump when fields are added; readers must accept legacy
.a2c/adoption.yaml shape.
5. Version migration (primary); layout migration (conditional)
Operators upgrade adoption with an explicit version migration command, e.g.
a2c migrate version --to X.Y.Z (name may vary; must not be folded into
a2c bootstrap).
Bootstrap remains adopt/scaffold for new or additive setup — not the upgrade path across layout eras.
Version migration:
- Update write contract / adoption record to target
V. - If
V(or the first version that mandates the new layout) requires.tools/esys/a2c/and.a2c/still exists:git mvtool-state files into.tools/esys/a2c/(adoption.yaml,config.yaml,cli-journal.yaml,migration.yaml, …)- Remove the empty
.a2c/directory - Prefer a single git commit for the move
- If both roots exist before migrate completes: prefer
.tools/esys/a2c/if present; otherwise fail or warn until migration finishes (no silent dual-write). - Ensure method assets for
Vare installable under.tools_local/esys/a2c/V/when delivery is package-oriented.
Layout change is a consequence of version migration when the target version’s contract requires it — not a standalone “migrate layout” product story.
6. Superbuild and multi-repo
- Superbuild may install the union of write-contract versions used by member
repos under
$WORKSPACE/.tools_local/esys/a2c/<ver>/. - Each member repo keeps its own tool state root and write contract.
- Superbuild-workflow remains at
$WORKSPACE/tools/ai-rules/(committed submodule or pin). A2C method installs do not replace that path.
6.1 Workspace root ($WORKSPACE / W)
$WORKSPACE / W is not an ambient environment variable. Discovering W
is the responsibility of the a2c CLI (shared library / commands such as
a2c workspace path). Agents and other tools call that API; they do not
re-implement discovery in prompts.
Path roles (committed marker at W vs local pointer under R), first-class
signals, parent-walk algorithm, and materializing
$R/.tools_local/esys/a2c/workspace.yaml are defined in
ADR-0025 — kept separate so discovery can
evolve (e.g. nested superbuilds) without reopening this ADR’s write-contract and
path bindings.
Once W is known, method resolution (§3) uses
$W/.tools_local/esys/a2c/V/ first. Agents must still never treat
$W/tools/ai-rules/ as the A2C method asset root.
7. Relationship to ADR-0013
This ADR supersedes ADR-0013. Adoption records, drift warnings, and bootstrap pinning intent remain; paths, delivery modes, write-contract semantics, and version migration are redefined here.
Consequences
Positive
- One ADR binds abstract roots to concrete paths — future moves do not fan out.
- Write contract matches existing “adopted version” without fake ranges.
- Superbuild and single-repo flows share the same resolution rules.
- Workspace discovery is owned by
a2c; algorithm details live in ADR-0025 so they can evolve separately. - Legacy
.a2c/and$R/tools/ai-rules/remain readable until version migration.
Negative
- Implementation must dual-read paths until consumers migrate.
- Agents and docs must stop treating every
tools/ai-rulesas A2C. - Agents must call
a2cforWrather than guess paths. - Package publishing of method assets and
a2c migrate versionare required follow-through (out of scope to fully implement in this ADR text alone).
Migration (operators)
- When ready to adopt a version that requires
.tools/esys/a2c/, runa2c migrate version --to X.Y.Z(or documented equivalent). - Review the
git mvof.a2c/→.tools/esys/a2c/. - Install method assets for
X.Y.Zinto.tools_local/esys/a2c/X.Y.Z/as directed by delivery mode / doctor.
References
- ADR-0013 — superseded adoption mount model
- ADR-0005 — product vs consumer repos
- ADR-0014 — journal under tool state root
- ADR-0016 — config under tool state root
- ADR-0017 — release config paths
- ADR-0018 — migration.yaml under tool state root
- ADR-0021 — Amends vs Supersede
- ADR-0025 — how
a2cdiscoversW - ADR-0027 — member
enumeration and method asset install into
.tools_local/(Proposed) - superbuild-workflow adr-conventions
Amends
- ADR-0005 — consumer tool state / method install layout
- ADR-0014 — journal path relative to tool state root
- ADR-0016 — config path relative to tool state root
- ADR-0017 — config path relative to tool state root
- ADR-0018 — migration.yaml path relative to tool state root
Amended by
- (none)
Supersedes
Superseded by
- (none)