Skip to content

Org-overridable metadata (view, dashboard) is accepted with a 200 state:'active' receipt but served by no read door #9454

Description

@os-zhuang

Extracted from Tier-2B (#9453, view) and Tier-2C (#9467, dashboard) of the QA wave #9296. Subject sha e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd, stock showcase.

Scope widened 2026-08-18. Filed first against view; the next round found the identical shape on dashboard, independently, with its own controls. Two metadata types, one mechanism — kept as one card because splitting it would invite two fixes for one defect and let the general case escape.

The defect

A runtime PUT of an org-overridable metadata type answers 200 with a receipt reporting state: 'active' plus a version and sequence number — the shape that tells an author "this is live". Nothing then serves it:

door result
direct GET of the item 404
scoped listing (?object=<object>) unchanged — the new item is absent
unfiltered listing absent
browser view: nothing renders · dashboard: "Dashboard Not Found"

Draft → publish behaves identically. The platform reports success in the same breath as not delivering it — declared ≠ enforced, in the direction hardest for an author to notice, because the write path says everything worked.

The acceptance half is correct — the read side is the bug

view and dashboard are deliberately in the org-overridable set (allowOrgOverride: true, packages/spec/src/kernel/metadata-plugin.zod.ts), which is exactly why a runtime PUT against a read-only showcase package is accepted rather than refused — unlike object, field, hook and seed, which carry allowOrgOverride: false and are correctly locked. So the 200 is right. The anomaly is that nothing reads the overlay back.

The org-overridable set is view, dashboard, report, translation, email_template. Two of the five are now measured broken by the same shape; the other three are untested and should be assumed affected until shown otherwise — that is the general case the fix has to address.

Evidence — the controls are what make this stand up

view (Tier-2B): 4 saves · 3 names · 2 objects · 2 independent boots.
dashboard (Tier-2C): 5 saves · 4 names · 2 boots, one of them a fresh DB with a different org id.

Controls measured on both, and they are the reason this is a defect rather than an observation:

  • Positive control — an item of the same type that ships with the package reads back normally through the same doors on the same boot. The read path is not simply broken.
  • Org-scoping confound ruled out — one sys_organization row, and it is the session's active org; dashboard additionally re-measured against a different org id on a fresh DB.
  • Storage control (dashboard) — the write is observable where it lands.

That combination separates "the write silently no-ops" from "the reader looks in the wrong place".

What a fix has to settle

Where the overlay write lands and why every read door misses it — at the overlay-resolution layer, not per type, or the remaining three types stay broken.

Pin it with a round-trip test: author at runtime, then read back through the direct GET and the scoped listing, for each org-overridable type. A test asserting only the 200 receipt passes today and proves nothing — that is precisely the gap this defect lives in, and why two rounds of a browser sweep were needed to find something the write path calls a success.

Left unlabelled for domain:* and unlevelled — routing and priority are the triage seat's call. Filed P1 by its checklist items, though "the platform reports active for metadata it will not serve, across a whole capability class" is an argument for re-levelling.

Activity

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

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions