---
name: forward-ref-squats-positional-key
description: "A citation minted for a not-yet-existing positional slot silently retargets when that slot is later filled — dangling announces itself, retargeted does not."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 064b128e-50ee-43e6-9102-3ef87b834e36
  modified: 2026-08-02T07:48:29.250Z
---

A reference to a **positional** key (row N, item #N) that is minted *before* that
position exists does not stay dangling — it gets **squatted** when an unrelated
entry later occupies the slot, and then reads as a valid citation pointing at the
wrong thing.

Specimen (spt-core, found 2026-08-02 doing releases#95): `5199464` (2026-07-15)
minted `FLAKE-LEDGER #15` for the HEAVY-AT-BIRTH classification ruling **without
adding a ledger row** — the table was 14 rows before that commit and 14 after.
The label spread to 20 more sites. `e1a3338` (2026-08-01) then appended a
genuinely unrelated row 15. Every `#15` citation in the tree had been resolving
to the wrong entry for a year.

**Why:** a dangling reference announces itself the moment someone follows it; a
retargeted one is indistinguishable from a correct one and survives review
forever. The positional key is what makes squatting possible — a name key cannot
be squatted, only left dangling.

**How to apply:**
- When dropping or adding a positional key, sweep the citations *by their actual
  resolution*, not just their existence: for each `#N`, check the entry at N is
  the thing the citing text describes. Date-vs-date is the cheapest tell
  (a citation minted 2026-07-15 cannot legitimately name a row added 2026-08-01).
- Convert a forward reference to a **ruling/entity name**, never a slot number.
  If the thing has no home, say so and route authoring to its owner rather than
  inventing the record from a secondary source.
- A prior sweep's negative ("nothing else references these") is only as wide as
  its file globs — re-run it unrestricted before trusting it. The brief here had
  checked `docs/*.md` and concluded zero; the real count was 25, mostly in
  `.rs`/`.toml`/`.yml`. See [[sweep-dispatch-site-counts]],
  [[zero-match-filter-reads-as-absent]].
