Filed by the domain:engine execution seat on behalf of the #14683 dev (PR #14767), whose dedup channels were both down at report time — repo-scoped REST returns 403 and MCP search_issues was rate-limited on the GraphQL pool — so it correctly declined to file blind and handed this over. This seat has now run the dedup and independently re-verified the code on origin/main; ⛔ line numbers below are re-derived, not copied from the report.
⛔ Ungraded and unrouted on purpose — no pm:* state, no domain:*. It lands in packages/metadata-protocol, which the lane table puts in domain:engine, but grading and routing are triage's.
The defect
PR #14767 (Part of #14683) makes getMetaItems — the plural verb — apply organizationIdForMetaRead itself, so a sweep is scoped per type rather than per request. The singular verb, getMetaItem, still applies no gate of its own and is still handed a raw active organization by its callers.
⭐ And on the singular verb the consequence is worse, because the two verbs combine their two partitions differently.
Verified at origin/main 224f8ea4a, packages/metadata-protocol/src/protocol.ts:7382-7383:
const record = (orgId ? await findOverlay(orgId) : undefined)
?? await findOverlay(null);
That ?? is precedence, not a union. So an org-scoped row does not merely join an answer — it replaces the env-wide one and becomes the single served document.
Compare the plural verb, which UNIONs queryByOrg(null) with queryByOrg(orgId) under org-wins-on-collision. There, naming an organization for a type with no per-org read channel can only add rows — the resurrection #14683 is about. Here it can substitute one.
⇒ On a type the registry declares allowOrgOverride: false, a pre-#6190 phantom org-scoped row — the kind loadMetaFromDb walks past and reportUnhydratableOrgScopedRows exists to warn about — is served instead of the live env-wide document, to a caller that asked for the live one.
The ungated callers
packages/runtime/src/domains/meta.ts passes a raw deps.resolveActiveOrganizationId(_context) straight through. Seven call sites in that file; the ones the reporting dev identified as reaching the singular verb are at :702, :744 (both hard-coded to type 'object', which is allowOrgOverride: false) and :763 (generic over singularType).
⚠️ The dev reported these as :703, :745 and :768; on origin/main today they are :702, :744, :763. Immaterial to the finding, recorded because whoever takes this must re-derive them again rather than trust either reading.
Why the reporting dev deliberately left it alone
Its card was scoped to getMetaItems, and there is a real argument that the singular verb is a different problem: it takes one type per request, so a caller CAN be right about its scope, and the REST by-name door at rest-server.ts:5661 already gates. The runtime/domains/meta.ts callers are the ones that do not.
⇒ So this may be a caller-side fix rather than the callee-side one #14683 ruled for the plural verb — which is exactly the question triage decided on #14683 and should decide again here rather than inherit. ⛔ This seat asserts no direction.
⚠️ One thing worth weighing while grading, because it cuts against simply copying #14683's answer: applying the predicate inside getMetaItem would need its own idempotence proof against the call sites that already gate, and the by-name REST door is one of them.
Dedup
search_issues "getMetaItem singular organization overlay precedence nullish coalescing phantom org-scoped row shadows env-wide row served document ungated caller raw active organization" → 19 results, top 8 read. #14683 and #13753 rank at the top, which is the firing control. Distinguished:
Nothing open names the singular verb's precedence read.
Re-check
git grep -n "?? await findOverlay(null)" origin/main -- packages/metadata-protocol/src/protocol.ts
git grep -n "resolveActiveOrganizationId" origin/main -- packages/runtime/src/domains/meta.ts
Control on the same file: git grep -c "findOverlay" origin/main -- packages/metadata-protocol/src/protocol.ts (expect ≥ 4).
Refs: #14683 / PR #14767 (the plural verb's fix; this is its singular twin) · #13753 (the parent card) · #6190 (the phantom rows) · #9454, #9727, #13406 (the same rule rediscovered one door at a time — this would be the next instalment).
Filed by the
domain:engineexecution seat on behalf of the #14683 dev (PR #14767), whose dedup channels were both down at report time — repo-scoped REST returns 403 and MCPsearch_issueswas rate-limited on the GraphQL pool — so it correctly declined to file blind and handed this over. This seat has now run the dedup and independently re-verified the code onorigin/main; ⛔ line numbers below are re-derived, not copied from the report.⛔ Ungraded and unrouted on purpose — no
pm:*state, nodomain:*. It lands inpackages/metadata-protocol, which the lane table puts indomain:engine, but grading and routing are triage's.The defect
PR #14767 (
Part of #14683) makesgetMetaItems— the plural verb — applyorganizationIdForMetaReaditself, so a sweep is scoped per type rather than per request. The singular verb,getMetaItem, still applies no gate of its own and is still handed a raw active organization by its callers.⭐ And on the singular verb the consequence is worse, because the two verbs combine their two partitions differently.
Verified at
origin/main224f8ea4a,packages/metadata-protocol/src/protocol.ts:7382-7383:That
??is precedence, not a union. So an org-scoped row does not merely join an answer — it replaces the env-wide one and becomes the single served document.Compare the plural verb, which UNIONs
queryByOrg(null)withqueryByOrg(orgId)under org-wins-on-collision. There, naming an organization for a type with no per-org read channel can only add rows — the resurrection #14683 is about. Here it can substitute one.⇒ On a type the registry declares
allowOrgOverride: false, a pre-#6190 phantom org-scoped row — the kindloadMetaFromDbwalks past andreportUnhydratableOrgScopedRowsexists to warn about — is served instead of the live env-wide document, to a caller that asked for the live one.The ungated callers
packages/runtime/src/domains/meta.tspasses a rawdeps.resolveActiveOrganizationId(_context)straight through. Seven call sites in that file; the ones the reporting dev identified as reaching the singular verb are at:702,:744(both hard-coded to type'object', which isallowOrgOverride: false) and:763(generic oversingularType).:703,:745and:768; onorigin/maintoday they are:702,:744,:763. Immaterial to the finding, recorded because whoever takes this must re-derive them again rather than trust either reading.Why the reporting dev deliberately left it alone
Its card was scoped to
getMetaItems, and there is a real argument that the singular verb is a different problem: it takes one type per request, so a caller CAN be right about its scope, and the REST by-name door atrest-server.ts:5661already gates. Theruntime/domains/meta.tscallers are the ones that do not.⇒ So this may be a caller-side fix rather than the callee-side one #14683 ruled for the plural verb — which is exactly the question triage decided on #14683 and should decide again here rather than inherit. ⛔ This seat asserts no direction.
getMetaItemwould need its own idempotence proof against the call sites that already gate, and the by-name REST door is one of them.Dedup
search_issues"getMetaItem singular organization overlay precedence nullish coalescing phantom org-scoped row shadows env-wide row served document ungated caller raw active organization" → 19 results, top 8 read. #14683 and #13753 rank at the top, which is the firing control. Distinguished:#10340territory PR fix(metadata-protocol): apply the allowOrgOverride read gate inside getMetaItems, so multi-type sweeps are scoped per type #14767's comment cites), not the singular verb's precedence combinator.organizationIdis dead on both ends — the audit read returns every org's rows for a (type, name), while its comment describes a scope filter that is not in the query #8747 (closed) —auditMetaItem'sorganizationIddead on both ends: a different verb.environmentId, never on org #6602 (closed) — an org-scoped overlay row reaching the process-wideSchemaRegistry: the write/hydration side.Nothing open names the singular verb's precedence read.
Re-check
Control on the same file:
git grep -c "findOverlay" origin/main -- packages/metadata-protocol/src/protocol.ts(expect ≥ 4).Refs: #14683 / PR #14767 (the plural verb's fix; this is its singular twin) · #13753 (the parent card) · #6190 (the phantom rows) · #9454, #9727, #13406 (the same rule rediscovered one door at a time — this would be the next instalment).