Repository navigation
Description
Sweep card (maintainer-directed, 2026-08-07; third member added 2026-08-08 after its ruling). One claim, one PR, three Fixes.
Admission criterion
A route serves a response shape that its declared
responseSchemadoes not describe — the contract under-declares, or mis-declares, what actually goes on the wire.
Members
| # | Route | Declared | Actually served | Ruled direction |
|---|---|---|---|---|
| #5882 | GET /meta/:type/:name?layers=true |
one responseSchema |
a third shape under ?layers=true |
decide per member (see below) |
| #5950 | GET /meta/:type/:name (non-cached branch) |
{type, name, item} |
also lock / lockReason / lockSource — the ADR-0008 OCC carrier |
decide per member (see below) |
| #6442 | GET /analytics/meta |
data: { cubes: CubeSchema[] } |
data: CubeMeta[] (a bare array, narrower projection) |
ruled: narrow the declaration (maintainer, 2026-08-08) |
#5882 and #5950 land on the same handler and would serialize under the same-file rule regardless, so bundling them costs nothing. #6442 is a different handler in a different package but hits the identical criterion and takes the identical shape of fix, so it reviews as one more checklist line.
Direction
#6442 is already decided: narrow AnalyticsMetadataResponseSchema.data to the CubeMeta[] projection — zero runtime change. The recorded return path if format is ever needed is to add the key to the CubeMeta projection (additive); ⛔ do not widen the endpoint to full cube definitions (that would push sql to clients — capability expansion without pull).
#5882 / #5950 are per-member calls: either declare what is served (extend the contract, discriminated where the shapes genuinely differ) or stop serving the undeclared part. #5950's carrier has a real consumer story (optimistic concurrency), so widening the declaration is the likely answer; #5882's third shape may instead deserve its own declared variant. ⛔ Do not silently pick the cheaper one — the PR states the choice and its reason per member.
Scope discipline
- Zero changes beyond the three members.
git diff --statcorresponds line-for-line to the checklist — the line between a sweep and a rider. - Refusal/validation assertions for genuinely invalid shapes stay verbatim; a widened contract may not shrink the guarded surface.
- New assertions must bear load: assert the substance (the OCC carrier is present and typed; the layered shape parses under its own variant;
/analytics/meta's response parses against the narrowed schema), never "the old assertion is gone". - Out-of-scope findings filed separately per PD chore: version packages #10.
Landing constraints
- Touches
packages/specgenerated baselines ⇒ os-regen four-step序 on every sync (git merge origin/main→git checkout origin/main -- <generated>→ commit the merge first, then regenerate wholesale → assert sibling entries survive). ⛔ Never a text merge; nevergen:schemawhile in MERGE state (os-regen 驱动指示的gen:schema在 merge 未 commit 时运行,会把 authorable-surface 锚点倒退回旧 merge-base —— 生成器写入、门全绿、静默撤销 main 的锚点推进 #5370). - Anchor assertion is
pnpm --filter @objectstack/spec check:authorable-surfacegreen;baseRevmay lag; ⛔ never hand-edit the anchor. GET /analytics/meta的已声明响应契约与实际响应不是同一个形状(data: { cubes: CubeSchema[] }vsdata: CubeMeta[]) #6442 regeneratescontent/docs/references/api/analytics.mdx(it currently publishes the wrong shape). The hand-writtendata-api.mdx:393-395already describes the array form correctly — leave it alone.
Review shape
By checklist, not diff order: one line per member — route + trigger | declared shape | actual shape | direction taken and why.
Filed unassigned. Member issues keep pm:queue but are excluded from batch selection while this card is open; all three close together when the PR merges.
Activity
[-][sweep] `GET /meta/:type/:name` serves two shapes its responseSchema never declares (#5882 #5950)[/-][+][sweep] Three routes serve a shape their responseSchema never declares (#5882 #5950 #6442)[/+]