Split from #7893. Filed by the PM on behalf of the dev agent, which measured it but could not file it: GitHub REST returned 403 on every call from its container (git transport works, the API does not). Full text preserved verbatim from its handover; the wording below is the dev's.
Unassigned, finding — grading belongs to the findings-triage round, not to the filer.
The observation
GET /api/v1/meta/field/<object>.<name> on a runtime-created field returns:
{"type":"field","name":"showcase_task.zz_probe",
"item":{"name":"zz_probe","label":"Probe","type":"text",
"_diagnostics":{"valid":true}},
"lock":"none","editable":true,"deletable":true}for a row that reaches no object's fields, and therefore no ObjectQL query, no physical column, and no GET /meta/object/:name.
⛔ valid is correctly computed and should NOT simply be flipped
computeMetadataDiagnostics (packages/metadata-protocol/src/metadata-diagnostics.ts) resolves the type's Zod schema and .safeParse()s the document, so valid: true asserts this document is well-formed — which is true.
The same function deliberately backs both the save path's 422 and the read path's diagnostics, so that — per its own doc comment — "a document's verdict cannot depend on whether it was being saved or being opened."That property is worth preserving, and it is why the fix here is not "make it say false".
The actual defect
Well-formed is the only axis the envelope has, and consumers read it as in-effect.
MetadataValidationResult already models a third state on a different axis: computeMetadataDiagnostics returns undefined when a type has no registered schema, and its contract requires callers to treat that as "no opinion — not as 'valid'". There is no equivalent state for "well-formed but consumed by nothing."
lock / editable / deletable compound it: they are computed elsewhere (not traced in this investigation) and positively advertise the row as a live, editable, deletable item.
Ask
Whichever way #7893 is decided, decide separately what a read-time diagnostic owes a caller about effectivity. If a type can persist rows that no read path consumes, the envelope should either distinguish "well-formed" from "in effect", or state plainly that it does not model effectivity at all.
This is the same false-compliance shape ADR-0049 forbids, one layer down from #7893 — and it survives #7893 either way: under the implement-write-through option it disappears for field but remains for any future fragment type; under the retire-the-channel option the rows already written stay in sys_metadata, still reporting valid: true.
Reproduction
Rebuild the four-arm probe from packages/runtime/src/meta-field-overlay-lock.test.ts's harness — PUT /field/showcase_task.zz_probe, then GET the same path.
⚠️Read the body at body.data.item. The dev's first run asserted against body.item, which returns [], and a defect assertion passed against an empty read. Any arm here needs an anti-vacuity control.
Dedup
Searched open issues for _diagnostics and for valid/effectivity wording before filing; the only hit is #7656, which is a distinct defect in the same envelope and worth reading alongside this one:
Both say the envelope's verdict is computed over the wrong subject; they point in opposite directions and have different fixes. ⚠️ Whoever takes either should read the other first — a change to what computeMetadataDiagnostics is fed could easily fix one and deepen the other.
Related
#7893 (parent) · #7656 (same envelope, opposite direction) · #7743 · ADR-0049
Split from #7893. Filed by the PM on behalf of the dev agent, which measured it but could not file it: GitHub REST returned 403 on every call from its container (git transport works, the API does not). Full text preserved verbatim from its handover; the wording below is the dev's.
Unassigned,
finding— grading belongs to the findings-triage round, not to the filer.The observation
GET /api/v1/meta/field/<object>.<name>on a runtime-created field returns:{"type":"field","name":"showcase_task.zz_probe", "item":{"name":"zz_probe","label":"Probe","type":"text", "_diagnostics":{"valid":true}}, "lock":"none","editable":true,"deletable":true}for a row that reaches no object's
fields, and therefore no ObjectQL query, no physical column, and noGET /meta/object/:name.⛔
validis correctly computed and should NOT simply be flippedcomputeMetadataDiagnostics(packages/metadata-protocol/src/metadata-diagnostics.ts) resolves the type's Zod schema and.safeParse()s the document, sovalid: trueasserts this document is well-formed — which is true.The same function deliberately backs both the save path's 422 and the read path's diagnostics, so that — per its own doc comment — "a document's verdict cannot depend on whether it was being saved or being opened."That property is worth preserving, and it is why the fix here is not "make it say false".
The actual defect
Well-formed is the only axis the envelope has, and consumers read it as in-effect.
MetadataValidationResultalready models a third state on a different axis:computeMetadataDiagnosticsreturnsundefinedwhen a type has no registered schema, and its contract requires callers to treat that as "no opinion — not as 'valid'". There is no equivalent state for "well-formed but consumed by nothing."lock/editable/deletablecompound it: they are computed elsewhere (not traced in this investigation) and positively advertise the row as a live, editable, deletable item.Ask
Whichever way #7893 is decided, decide separately what a read-time diagnostic owes a caller about effectivity. If a type can persist rows that no read path consumes, the envelope should either distinguish "well-formed" from "in effect", or state plainly that it does not model effectivity at all.
This is the same false-compliance shape ADR-0049 forbids, one layer down from #7893 — and it survives #7893 either way: under the implement-write-through option it disappears for
fieldbut remains for any future fragment type; under the retire-the-channel option the rows already written stay insys_metadata, still reportingvalid: true.Reproduction
Rebuild the four-arm probe from
packages/runtime/src/meta-field-overlay-lock.test.ts's harness —PUT /field/showcase_task.zz_probe, thenGETthe same path.body.data.item. The dev's first run asserted againstbody.item, which returns[], and a defect assertion passed against an empty read. Any arm here needs an anti-vacuity control.Dedup
Searched open issues for
_diagnosticsand forvalid/effectivity wording before filing; the only hit is #7656, which is a distinct defect in the same envelope and worth reading alongside this one:_diagnostics.valid:**false**when it should be true (the read injects_draft, then validates it)._diagnostics.valid:**true**when nothing consumes the row.Both say the envelope's verdict is computed over the wrong subject; they point in opposite directions and have different fixes.⚠️ Whoever takes either should read the other first — a change to what
computeMetadataDiagnosticsis fed could easily fix one and deepen the other.Related
#7893 (parent) · #7656 (same envelope, opposite direction) · #7743 · ADR-0049