48 lines
1.9 KiB
Markdown
48 lines
1.9 KiB
Markdown
|
|
# ADR-0005 — Revision identity
|
||
|
|
|
||
|
|
**Status:** accepted · **Date:** 2026-09-04
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
Blueprint §54 lists this as deliberately open: "Should revision numbering be
|
||
|
|
global, per interface, semantic, or content-addressed?" It asks for the answer
|
||
|
|
to come from implementation experience rather than premature standardization.
|
||
|
|
|
||
|
|
An answer is nonetheless needed before anything can be published, so this ADR
|
||
|
|
picks the smallest one that does not foreclose the others.
|
||
|
|
|
||
|
|
## Decision
|
||
|
|
|
||
|
|
Two identifiers, with different jobs.
|
||
|
|
|
||
|
|
**A human-facing revision id, sequential per interface.** `R-000221` with a
|
||
|
|
`revision_number` of 22, both scoped to one interface. This is what appears in
|
||
|
|
audit trails, CLI output and conversation.
|
||
|
|
|
||
|
|
**A content address for every artifact the revision names.** The contract and
|
||
|
|
the implementation each carry a `sha256:` digest. A revision is reproducibly
|
||
|
|
associated with its artifacts through those digests, per Blueprint §25.
|
||
|
|
|
||
|
|
Identity is therefore human-sequential; equality is content-addressed.
|
||
|
|
|
||
|
|
## Rationale
|
||
|
|
|
||
|
|
Global numbering was rejected: it couples unrelated interfaces and makes the
|
||
|
|
number meaningless as a lineage signal.
|
||
|
|
|
||
|
|
Purely content-addressed identity was rejected as the primary handle. Digests
|
||
|
|
are correct but unreadable, and Blueprint §16 of the schema spec is explicit
|
||
|
|
that human-readable prefixes are recommended for operational tooling. A framework
|
||
|
|
whose central concept cannot be said out loud will not get used carefully.
|
||
|
|
|
||
|
|
Semantic versioning was rejected because compatibility is already declared
|
||
|
|
separately, in `compatibility.class`. Encoding it a second time in the
|
||
|
|
identifier invites the two to disagree.
|
||
|
|
|
||
|
|
## What stays open
|
||
|
|
|
||
|
|
Whether `revision_number` should be dense (no gaps) is unresolved. Failed
|
||
|
|
candidates currently consume a number. That is defensible — the attempt is part
|
||
|
|
of the history — but it may prove noisy. Revisit after the first real interface
|
||
|
|
has produced enough failed candidates to tell.
|