Measured by the dev seat implementing #9190 (PR #9324). ⛔ Filed by the PM on that seat's behalf — it was blocked by the shared GitHub API rate limit and could not run the dedup search that filing requires. The measurement is theirs; the dedup search has now been run.
The mismatch
Two spellings of "a field" that never meet:
So GET /api/v1/meta/field/account.owner/references scans ten source types and answers [] on every deployment, regardless of content. The sites that genuinely point at that field hold owner, and nothing compares owner to account.owner.
What this is and is not
⭐ Derivation made this visible; it did not cause it. The same mismatch existed under the hand-curated REFERENCE_PATHS — it was simply indistinguishable from the general silence, because field was one of twenty-plus types the table had never heard of. #9324 removed that silence for the other types and left this one standing alone, which is why it is now nameable.
⛔ It is not a missing path. Adding more matchers cannot fix it: the paths are already derived and already correct. The two sides disagree about what a field's name is, and no path expression reconciles a qualified key with a bare one without deciding which is canonical.
Why it matters
Same consumer, same harm shape as the layer #9324 closed: the "Used by" panel renders before a rename or delete, and its empty state reads
'engine.edit.refsEmptyDesc': 'Nothing in the metadata graph points at this item. Safe to delete.'
A field is one of the more dangerous things to delete on a false negative — columns, validations and dimensions referencing it break silently at render time rather than at delete time.
The decision this needs
A name-form decision, not an implementation:
- Qualify at the site — treat a bare
field value as <enclosing object>.<field> when deriving, using the source item's own object as the scope. Correct where the enclosing object is knowable; needs a stated answer for sites where it is not.
- Unqualify at the lookup — match on the bare segment of the target key. Cheapest, and wrong across objects:
account.owner and contact.owner would collide into one answer.
- Both, explicitly scoped — qualify where derivable, and refuse (rather than silently under-report) where not.
Option 2 is the one that looks easiest and produces confidently wrong answers, which on this consumer is worse than the current confidently-empty ones.
Re-check
grep -n "7893" packages/metadata-protocol/src/*.ts
grep -rn "columns\[\]\.field\|dimensions\[\]\.field" packages/metadata-protocol/src/reference-sites.ts
Related: #9190 / PR #9324 (derivation, closed — this is its named residue), #9537 (the capability-gap layer above), ADR-0110 D3.
Measured by the dev seat implementing #9190 (PR #9324). ⛔ Filed by the PM on that seat's behalf — it was blocked by the shared GitHub API rate limit and could not run the dedup search that filing requires. The measurement is theirs; the dedup search has now been run.
The mismatch
Two spellings of "a field" that never meet:
<object>.<field>— recorded in the meta-field-write-inert: an acceptedfieldPUT never reaches the object — a runtime-created field is storedvalid=trueand is absent fromfieldsforever #7893 comment onDEFAULT_METADATA_TYPE_REGISTRY. That is the identity a/referenceslookup is given.view.config.columns[].field,dataset.dimensions[].field,object.validations[].field, and roughly thirty more.So
GET /api/v1/meta/field/account.owner/referencesscans ten source types and answers[]on every deployment, regardless of content. The sites that genuinely point at that field holdowner, and nothing comparesownertoaccount.owner.What this is and is not
⭐ Derivation made this visible; it did not cause it. The same mismatch existed under the hand-curated
REFERENCE_PATHS— it was simply indistinguishable from the general silence, becausefieldwas one of twenty-plus types the table had never heard of. #9324 removed that silence for the other types and left this one standing alone, which is why it is now nameable.⛔ It is not a missing path. Adding more matchers cannot fix it: the paths are already derived and already correct. The two sides disagree about what a field's name is, and no path expression reconciles a qualified key with a bare one without deciding which is canonical.
Why it matters
Same consumer, same harm shape as the layer #9324 closed: the "Used by" panel renders before a rename or delete, and its empty state reads
A field is one of the more dangerous things to delete on a false negative — columns, validations and dimensions referencing it break silently at render time rather than at delete time.
The decision this needs
A name-form decision, not an implementation:
fieldvalue as<enclosing object>.<field>when deriving, using the source item's own object as the scope. Correct where the enclosing object is knowable; needs a stated answer for sites where it is not.account.ownerandcontact.ownerwould collide into one answer.Option 2 is the one that looks easiest and produces confidently wrong answers, which on this consumer is worse than the current confidently-empty ones.
Re-check
Related: #9190 / PR #9324 (derivation, closed — this is its named residue), #9537 (the capability-gap layer above), ADR-0110 D3.