ADR 007 revision 7: hand-written ids are canonical (improvise-sboz)
Answer 29: the gensym suffix only ever goes on a generated id; an id read from a file is never renamed, and two identical hand-written ids refuse the load (answers 11, 22, 29). No question open; still proposed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# ADR 007 — Stable identities for categories, items, formulas and views
|
||||
|
||||
**Status:** proposed (2026-09-24). Revision 6 folds in the user's fifth round of
|
||||
answers, and **no question is left open**. Revision 4 checked the ADR against work
|
||||
**Status:** proposed (2026-09-24). Revision 7 folds in the user's sixth round, one
|
||||
answer, and **no question is left open**. Revision 4 checked the ADR against work
|
||||
that landed since revision 1. This ADR is not accepted until the user says it is. ·
|
||||
**Decided by:** the user, in part; see "What the user decided" ·
|
||||
**Ticket:** improvise-sboz · **Unblocks:** improvise-fz77, improvise-fdk1 ·
|
||||
@@ -300,6 +300,24 @@ This decides three things:
|
||||
Clause 4 is rewritten to match. The rules this replaces (lowest free number, and
|
||||
suffixing only on import) were revision 5's.
|
||||
|
||||
### Sixth round: answer on revision 6
|
||||
|
||||
The user replied at 2026-09-24 22:09Z to their own answer 28, on line 782 of
|
||||
`e044c968`:
|
||||
|
||||
**29. Hand-written ids are canonical.**
|
||||
|
||||
> "You have to treat the file's hand-written ids as canonical, doing otherwise will
|
||||
> corrupt the data section."
|
||||
|
||||
This constrains answer 28. The `gensym` suffix applies only to an id the program is
|
||||
**generating**, on import, when an id-less file loads, or when the host creates
|
||||
something in a session. **An id written in a file is never renamed**, because every
|
||||
data key and reference in that file spells it. Clause 4 says what follows:
|
||||
- a generated id that would collide with a file's id takes the suffix, and the file's
|
||||
id keeps its spelling;
|
||||
- two identical hand-written ids in one file are refused at load, not repaired.
|
||||
|
||||
## Context
|
||||
|
||||
**Today the name is the identity.** `Model::categories` is an `IndexMap` keyed by name.
|
||||
@@ -468,11 +486,20 @@ The remaining rules:
|
||||
removed is still reserved in memory.
|
||||
- **Determinism:** the counter advances in file order or creation order, so the same
|
||||
input gives the same ids, never hash order (gotcha 18).
|
||||
- **This ADR's reading:** where a candidate `slug-<n>` is itself already taken, for
|
||||
example because a new-version file spelled it by hand, the counter advances again
|
||||
until the candidate is free. The counter lives in memory and starts at 1 when a
|
||||
document loads. It is not written to the file, since retired ids are not persisted
|
||||
(answer 13).
|
||||
- **Hand-written ids are canonical** (answer 29). The suffix only ever goes on the
|
||||
id being generated. An id read from a new-version file keeps its spelling, even
|
||||
when it looks like a slug or a suffixed one (`east-3`), because the file's data
|
||||
keys and references spell it. So when a generated candidate `slug-<n>` is already
|
||||
taken by a file's id, the counter advances again until the candidate is free.
|
||||
- **Two identical hand-written ids in one file are refused at load** (answers 11,
|
||||
22 and 29). By answer 22 they are a duplicate even when they declare different
|
||||
kinds of thing, such as a category and an item. Renaming either one is exactly
|
||||
what answer 29 forbids, and answer 11 already refuses a duplicate because such a
|
||||
file "can't safely resave". The error names both lines (clause 5). This follows
|
||||
from the answers, so it is not asked as a new question.
|
||||
- **The counter** lives in memory and starts at 1 when a document loads. It is not
|
||||
written to the file, since retired ids are not persisted (answer 13). That is
|
||||
this ADR's reading.
|
||||
- **Across a save and reload, reuse is accepted** (answer 13, Q10(b)). Retired ids are
|
||||
not persisted. So remove `East`, save, reload and add `East`, and the new item gets
|
||||
`east` again. An in-flight command from before the reload is refused by the
|
||||
@@ -560,7 +587,8 @@ the walker drops such lines, so without its own strategy every formula property
|
||||
vacuous (improvise-rxz9).
|
||||
|
||||
**A duplicate, unknown or missing id in a new-version file refuses the load** (answers
|
||||
11 and 21; answer 11:
|
||||
11, 21, 22 and 29; a duplicate across two kinds of thing counts, and a hand-written id
|
||||
is never renamed to resolve one; answer 11:
|
||||
"don't load the file because you can't safely resave it"). The error names the id,
|
||||
and for a duplicate it names both declarations. Repairing silently is ruled out,
|
||||
because references carry ids (answer 3): reassigning a duplicate would silently change
|
||||
@@ -803,11 +831,12 @@ are answered.**
|
||||
| 20 | Virtual category ids | (a) lower-case ids, capitalised displays | **answered: (a)**, and no other id may begin with `_` (answer 23) |
|
||||
| 21 | An old file naming an undeclared item | (a) declare it at load | **answered: (a)** (answer 24) |
|
||||
| — | "A new file version" (a Consequences line) | — | **answered**: the version must be explicit (answer 25); it already is, and clause 10 adds a second literal |
|
||||
| 22 | The suffix's spelling, and interactive collisions | (a) plain number; (b)(i) suffix there too | **answered**: a plain number (answer 27); any collision is suffixed, across kinds, from a `gensym`-style increment-only counter (answer 28) |
|
||||
| 22 | The suffix's spelling, and interactive collisions | (a) plain number; (b)(i) suffix there too | **answered**: a plain number (answer 27); any collision is suffixed, across kinds, from a `gensym`-style increment-only counter (answer 28), and only a generated id is ever suffixed, since a hand-written one is canonical (answer 29) |
|
||||
|
||||
## Still open
|
||||
|
||||
Nothing. Every question Q1–Q22 is answered. This ADR still waits on the user's
|
||||
Nothing. Every question Q1–Q22 is answered, and answer 29 settles the one case it
|
||||
raises: two identical hand-written ids are refused at load. This ADR still waits on the user's
|
||||
explicit "Approved" before it is Accepted.
|
||||
|
||||
## Consequences
|
||||
|
||||
Reference in New Issue
Block a user