Skip to content

[Decision] GetMetaItemRequestSchema (:271) and GetMetaItemLayeredRequestSchema (:441) organizationId describes are now measurably FALSE — correct them, or leave all of them until ADR-0131 C5 deletes the surface? #16524

Description

@huangyiirene

Filed by the domain:spec PM seat (session_01T6HeZvT9wdSJD1ZxJb5Eno, seat post #6017), carrying forward the second open question from #14772's dev (report on PR #16523). ⛔ Decision-box: the maintainer capped #14772 at one row, and the premise that cap partly rested on has since been falsified. This card exists so that falsification reaches the person who wrote the cap.

⛔ Not dispatchable while this carries needs-user-decision.

What changed since the cap

Maintainer hotlong capped #14772 on 2026-09-04 (comment 5536474187): fix :236 only, minimum true sentence, ⛔ no registry clause, ⛔ do not touch :271 / :441 / :1815. :236 is now fixed and landing (PR #16523).

One of the cap's two stated reasons was that the other rows are accurate today — inherited from the card's own opening table. That is no longer true, and it is no longer a matter of inference.

The measurement, taken twice and independently

Anchored to the literal sha c383352cb752245899b6ca7e2dc7d233405113ee.

Layer 1 — the gate is invoked (this seat, before dispatch): organizationIdForMetaRead(request.type, request.organizationId) is called inside three verbs — getMetaItems (:7056), getMetaItem (:7688), getMetaItemLayered (:8198). I deliberately hedged this as a read of the call, not of the consequence.

Layer 2 — the consequence (#14772's dev, and re-verified by this seat line by line):

verb what a gated-away orgId does
getMetaItems :7159 const orgRecords = orgId ? await queryByOrg(orgId) : []no org rows read
getMetaItem :7726 const draftRec = (orgId ? await findDraft(orgId) : undefined) ?? await findDraft(null)falls straight to env-level
getMetaItemLayered :8293-8294 if (orgId) { const rec = await findOverlay(orgId); … }no overlay read at all

:271 and :441 are FALSE in exactly the way :236 was — a supplied organizationId is dropped for any allowOrgOverride: false type, and no org partition is consulted. This is a reading of the consequence, not of the call.

✅ Also resolved: a fourth gate call site exists at :11641, organizationIdForMetaRead('page', request.context?.tenantId). It uses a literal 'page', which is why it correctly falls outside the request.type grep. Nothing hidden there.

The decision

A — leave all of them until ADR-0131 C5 deletes the surface. The maintainer's own cheaper answer, named in the cap: "at that point 'leave all four alone until C5 deletes them' is the cheaper answer, and it is the maintainer's call."

B — apply the same minimal correction to :271 and :441 in a follow-up card (:1815 inherits :271 by its own wording). Same shape as #16523: qualify the promise, state the negative, ⛔ no registry clause, ⛔ no new key.

C — widening #14772's PR — is excluded outright and was never on the table: triage's standing instruction (5519715058) is explicit that a reading showing :271 already imprecise is to be reported, not acted on. It was reported. #16523 held at one row.

The four axes

  • 实际业务需求 — these are published describe()s compiling into the generated API reference; they are what an integrator reads to decide whether to send the field. Three of them currently tell that integrator the parameter does something it does not do. ⚠️ But measured harm is bounded: ADR-0005 says a non-overridable type has no legitimate tenant rows, so nothing leaks — this is precision, not correctness, exactly as the original card graded it (p3).
  • 项目长远合理性 (≥50%) — this is the axis that actually decides, and it turns on one fact this seat cannot measure: does ADR-0131 C5 (feat(metadata-core,metadata-protocol,objectql,plugin-security): the sys_metadata family goes tenant-less; the per-organization overlay axis retires; managed content is sealed (ADR-0131 D6/D7/D13) #15206) land inside roughly one release? If yes, A is right and B pays a changeset in and another out for prose with weeks to live. If C5 slips, three published describes stay false for however long it slips — and "we'll fix it when C5 lands" is precisely how a temporary state becomes permanent by forgetting. That is the same failure mode the ci.yml wall raise wrote an explicit revert condition to avoid.
  • 防 AI 写代码犯错 — an AI author reading "present ⇒ consulted" writes an organizationId into a metadata read believing it scopes it. The refusal is silent (the read simply goes environment-wide), so the mistake is not surfaced. Prose that contradicts enforced behaviour teaches the wrong reflex — the general principle the docs: the manifest surface no longer describes itself as an open object #16327 diff just landed on the manifest surface for the same reason.
  • 创业阶段不扩散需求 — B adds no capability and no key; it is three sentences. It does not widen anything. But it is also not free: a published describe() costs a changeset each way, which is the maintainer's stated objection.

This seat's recommendation

B, but weakly, and A is entirely defensible. The dev recommended B over C and left A-vs-B to the maintainer; I agree with that division. The deciding input is the C5 schedule, which the maintainer has and I do not. ⛔ I am not treating the falsified premise as licence to overturn the cap — only as reason to put it back in front of the person who set it.

If the answer is A, that is a complete answer and this card closes; ⚠️ please say so explicitly rather than leaving it open, so the next seat does not re-derive this.

Refs: #14772 · PR #16523 · #14770 · #15206 (ADR-0131 C5) · ADR-0131 D6/D7 · ADR-0005.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions