Skip to main content

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 a2c CLI does not surface that the repository was adopted with an older version.
  • a2c bootstrap --with-ai-rules submodule|clone can leave tools/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).

FieldSemantics
tool_versionA2C CLI version at first adoption — frozen on first write; never overwritten
recorded_atISO-8601 UTC timestamp of first write
first_commandinit or bootstrap — which command created the file
deliverynone, copy, submodule, or clone — updated when a2c bootstrap runs
method_refExpected method version: git tag or commit for mount modes; vX.Y.Z for copy
method_repo_urlSource 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:

  1. Adopted CLI vs running CLItool_version in .a2c/adoption.yaml vs a2c_core.__version__
  2. Installed method vs recorded method — for a git checkout at tools/ai-rules/, resolved tag or commit vs method_ref
  3. Installed method vs current CLI — mounted ref vs expected v{current CLI version}
  4. Copy delivery — recorded method_ref vs expected v{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 doctor reports 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.yaml emit no drift warnings until init or bootstrap creates the file.

5. Relationship to consumer ADR-0000

ArtifactRole
docs/adr/0000-adopt-a2c-workflow.md (consumer)Human architectural record of the adoption decision
.a2c/adoption.yamlMachine-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_version means 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 constant ADOPTION_FILE in a2c_core.contracts.paths