spec: design-ledger-formal-links — recon-driven amendment (clause-6 + cross-ref definition)

Planner Step-2 recon (ailang-plan-recon) surfaced two spec defects;
forward-fix amendment (63b669f stands, main forward-only):

- clause-6 homeless-ref remedy was an incomplete binary. Recon proved
  roundtrip-invariant.md does NOT carry the ail-merge-prose-cycle
  content that pipeline.md:61 / authoring-surface.md:180 cite — so the
  prior canonical retarget sample was wrong. Replaced with three
  priority-ordered dispositions; PROSE_ROUNDTRIP refs take (b) (drop
  the cross-tier pointer, preserve the present-tense behavioural prose).
- Added a precise 'what counts as a cross-reference' definition:
  navigational pointer = in scope; nominal source-symbol mention = out
  of scope (keeps the milestone 'formalise the cross-references', not
  'hyperlink the ledger'). Source link only for a genuine navigational
  (see crates/...). Folds OQ2 (strip iter-provenance suffixes on
  conversion) + OQ3 (no-title directional stays prose) as byte-policies.

grounding-check re-dispatched on the amended bytes: PASS, all
assumptions ratified incl. the amendment-introduced ones.
This commit is contained in:
2026-05-19 23:03:03 +02:00
parent 63b669fa8f
commit b1a0364bf2
@@ -93,14 +93,27 @@ not forks):
These stay as prose. The remedy for "this file is too big for
'above' to be clear" is commitment 1's file-split — a separate
future concern, explicitly NOT this milestone.
- **Homeless references resolve or die.** A prose reference whose
referent has no durable home (e.g.
`design/models/pipeline.md``(see docs/PROSE_ROUNDTRIP.md)`)
is retargeted to the durable file that carries the content today
(here: `../contracts/roundtrip-invariant.md`) if one exists, else
deleted as decision-record-class prose (clause-3 already forbids
the relitigation form). Enumerating them is a recon/plan-time
scan, not a spec byte-decision.
- **Homeless references — three dispositions (clause-6), in
priority order.** A cross-reference whose referent has no durable
home is: **(a)** retargeted to the durable `design/`-or-source
file that *actually carries that content* today, if one exists;
else **(b)** the parenthetical pointer is removed while the
surrounding present-tense behavioural prose is preserved verbatim
the ledger *describes* the behaviour, it does not point into
the non-durable tier; else **(c)** deleted outright **only if the
reference itself is relitigation residue** (clause-3-class).
Recon-confirmed canonical instance:
`design/models/pipeline.md:61` and
`design/models/authoring-surface.md:180`, both
`(see docs/PROSE_ROUNDTRIP.md)`, cite the *prose-mediator cycle /
`ail merge-prose`* — content
`design/contracts/roundtrip-invariant.md` does **not** carry
(that contract is the orthogonal hashing / parse-determinism
invariant). (a) is therefore unavailable and the content is real
current behaviour, not relitigation, so the disposition is
**(b)**: drop the `(see docs/PROSE_ROUNDTRIP.md)` pointer, keep
the surrounding `ail merge-prose` prose intact. Enumerating every
instance is the recon's job; the *policy* is the spec's.
- **A cross-*file* `§"Section"` reference becomes a file-link.**
`(see §"Data model" …)` pointing at content in *another* file
becomes `[Data model](data-model.md)` — the section title may
@@ -111,6 +124,49 @@ not forks):
file is intra-file directional prose — the bullet above — and is
untouched.)
## Scope — what counts as a cross-reference
The milestone formalises **navigational cross-references**, not
every nominal mention of a file or symbol. The discriminator:
- **In scope (a cross-reference):** a *navigational pointer* — the
reader is being told to go look elsewhere. Forms: `(see "Title"
…)`, `(see §"Section" …)`, `(see <path>)`, `… as in <X> …`, a
bare in-prose path inside a `(see …)`, or a directional `…
below`/`… above` whose named target is a **different file**.
These convert to file-relative `[label](path)` Markdown links.
- **Out of scope (not a cross-reference):** a *nominal mention* of
a source symbol or path in explanatory prose — "the desugarer
`ailang-core::desugar` lowers loop-recur", "the box layout in
`crates/ail-embed/src/lib.rs`". Naming the implementation is not
pointing the reader at a document to read. Linkifying these would
make the milestone "hyperlink the whole ledger" rather than
"formalise the cross-references" — a different, unrequested
change. They stay as prose. Commitment 2 *permits* a `crates/**`
link target only for the case where a genuine navigational `(see
crates/… )` pointer exists — e.g. `scope-boundaries.md:88` `see
\`ailang-core::desugar\`` converts to
`[desugar](../../crates/ailang-core/src/desugar.rs)` — never for
a nominal mention.
Two byte-policies the conversion applies (Boss-adjudicated from
recon Open Questions; the planner does not re-open them):
- **Iter-provenance suffixes are stripped on conversion.** A
reference like `see §"Class names" / mq.1` carries a
clause-3-class iter token. Converting yields
`[Class names](typeclasses.md)` — the ` / mq.1` provenance is
removed (it is exactly what clause-3 forbids; the
clause-3 ∘ clause-5 composition requires its removal, not its
survival riding on a now-formal link).
- **A directional phrase with no quoted title and no `(see …)`
form stays prose.** `embedding-abi.md:51` "the frozen value
layout below specifies" has no title to become a link label and
is not a `(see …)` pointer — descriptive directional prose, left
untouched. (The genuine cross-file pointer for that referent is
the *separate* `embedding-abi.md:45` `(see "Frozen value layout"
below)`, which does convert.)
## Concrete code shapes
### No authoring surface — the delivered concrete code
@@ -261,13 +317,21 @@ design/contracts/embedding-abi.md:45 (informal AND stale-direction
- after: … layout is **frozen as of M3** (see
[Frozen value layout](frozen-value-layout.md)); …
design/models/pipeline.md:61 (the canonical HOMELESS reference —
points into docs/, the non-durable tier)
- before: … (see docs/PROSE_ROUNDTRIP.md)
- after: … (see [round-trip invariant](../contracts/roundtrip-invariant.md))
# retargeted to the durable home that carries the
# content; if recon finds no durable home, the clause-6
# rule deletes it as decision-record-class prose instead
design/models/pipeline.md:61 + design/models/authoring-surface.md:180
(the canonical HOMELESS references — `(see docs/PROSE_ROUNDTRIP.md)`
into the non-durable tier; recon proved roundtrip-invariant.md
does NOT carry the merge-prose-cycle content ⇒ clause-6
disposition (b), not a retarget)
- before (shape): … the prompt template `ail merge-prose`
composes (see docs/PROSE_ROUNDTRIP.md).
- after (shape): … the prompt template `ail merge-prose`
composes.
# disposition (b): the (see docs/…) pointer is removed;
# the surrounding present-tense behavioural prose about
# `ail merge-prose` is preserved verbatim. Exact bytes
# (recon-confirmed pipeline.md:60-61,
# authoring-surface.md:180-181) are the planner's per
# the planner Iron Law.
```
### (c) clause-1 is unchanged (commitment 4, INDEX = spine)
@@ -344,12 +408,19 @@ outcome, not a dodge).
2. clause-5 is demonstrably RED-able (the synthetic vector fails if
the durable classifier or the anchor check is wrong) and GREEN on
the final tree.
3. Every genuine cross-*file* prose reference in `design/contracts/`
and `design/models/` is a file-relative `[label](path)` Markdown
3. Every *navigational* cross-*file* reference (per §"Scope — what
counts as a cross-reference") in `design/contracts/` and
`design/models/` is a file-relative `[label](path)` Markdown
link resolving (from its containing file) to an existing
`design/`-or-source file. The float-semantics, embedding-abi, and
pipeline references above are converted exactly as shown (modulo
recon's homeless-home confirmation).
`design/`-or-source file — OR, for a homeless reference, is
disposed per clause-6 (a)/(b)/(c). Nominal source-symbol
mentions are NOT linkified (out of scope). Iter-provenance
suffixes on converted refs are stripped. The recon enumeration
is the authoritative touch-set: float-semantics:100,
float-semantics:69, embedding-abi:45, data-model:38/66/79/206/226,
memory-model:44/105, scope-boundaries:48/88 convert; the two
PROSE_ROUNDTRIP refs take disposition (b); embedding-abi:51 and
every intra-file "above/below" stay prose.
4. No reference in `design/` targets `docs/` (any subtree) or
carries a `#fragment`.
5. `design/INDEX.md` and clause-1 are byte-unchanged; the