What
objectui#7603 fixed ResourceEditPage by stripping the spec's METADATA_READ_DECORATIONS
(_diagnostics, _draft) in extractDraftBody — the chokepoint its three merge sites share.
Three other modules read the same decorated envelope and strip nothing. Filed unassigned
for PM triage; found while implementing objectui#7603 and deliberately left untouched there.
client.getDraft() serves a decorated body: the strict draft branch returns
item: decorateMetadataItem(type, ...), which attaches _diagnostics whenever the type has a
registered Zod schema. Measured on the bundled spec, PageSchema.safeParse on a body plus
_diagnostics returns unrecognized_keys.
The three sites, measured on origin/main 9bfd61848
| site |
line |
shape |
packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx |
445, 453-455 |
((pendingDraft as any).item ?? pendingDraft) becomes effective, which seeds draft |
packages/app-shell/src/views/studio-design/ObjectHooksPanel.tsx |
42-47, 139 |
its own local draftBody() helper, same shape as the pre-fix extractDraftBody |
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx |
1730, 1856, 2845, 3881 |
four getDraft reads |
Each is the pre-objectui#7603 extractDraftBody shape: presence check, emptiness check, body
returned verbatim.
What is and is not measured
Measured: none of the three passes the body through stripReadDecorations, and none has a
local equivalent — grep -c stripReadDecorations is 0 in all three files, while the same grep
returns 2 in ResourceEditPage.tsx (post-fix) and 3 in MetadataService.ts. The zero is
backed by a firing control: grep -c client on the same three files returns 20 / 12 / 55, so
the grep shape does reach these files.
NOT measured — this is why the card is filed rather than fixed: whether a decorated body
actually reaches a gate or a write on any of these paths. One narrow leak is visible by reading
PermissionMatrixEditor.doSave: under the package door it builds
base = fresh?.effective ?? payload and then merged = { ...base }, so decorations are dropped
whenever the fresh layered read succeeds (effective is a RAW layer) — but the .catch(() => null) arm falls back to payload, which is the decorated draft, and spreads it into the save.
That is a failure-path-only leak and it has not been exercised.
Why it is worth a card anyway
The framework has now paid for this class three times (a served _diagnostics 400ing every
saved dataset; the cold-boot flow bind in cloud#971; and objectui#7603 itself). The remaining
value here is that a fourth site is one copy-paste away: ObjectHooksPanel already carries a
hand-rolled duplicate of the helper objectui#7603 just fixed, so the next author who copies it
inherits the defect and not the cure.
Suggested shape, not a decision
Consider one shared draft-envelope reader that all consumers call, deriving the key list from
the spec's exported stripReadDecorations rather than restating it. Triage should decide
whether that is worth the refactor or whether the three sites should simply be measured and
left alone. Not urgent, and expressly not a request to loosen any schema.
What
objectui#7603 fixed
ResourceEditPageby stripping the spec'sMETADATA_READ_DECORATIONS(
_diagnostics,_draft) inextractDraftBody— the chokepoint its three merge sites share.Three other modules read the same decorated envelope and strip nothing. Filed unassigned
for PM triage; found while implementing objectui#7603 and deliberately left untouched there.
client.getDraft()serves a decorated body: the strict draft branch returnsitem: decorateMetadataItem(type, ...), which attaches_diagnosticswhenever the type has aregistered Zod schema. Measured on the bundled spec,
PageSchema.safeParseon a body plus_diagnosticsreturnsunrecognized_keys.The three sites, measured on
origin/main9bfd61848packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx((pendingDraft as any).item ?? pendingDraft)becomeseffective, which seedsdraftpackages/app-shell/src/views/studio-design/ObjectHooksPanel.tsxdraftBody()helper, same shape as the pre-fixextractDraftBodypackages/app-shell/src/views/studio-design/StudioDesignSurface.tsxgetDraftreadsEach is the pre-objectui#7603
extractDraftBodyshape: presence check, emptiness check, bodyreturned verbatim.
What is and is not measured
Measured: none of the three passes the body through
stripReadDecorations, and none has alocal equivalent —
grep -c stripReadDecorationsis 0 in all three files, while the same grepreturns 2 in
ResourceEditPage.tsx(post-fix) and 3 inMetadataService.ts. The zero isbacked by a firing control:
grep -c clienton the same three files returns 20 / 12 / 55, sothe grep shape does reach these files.
NOT measured — this is why the card is filed rather than fixed: whether a decorated body
actually reaches a gate or a write on any of these paths. One narrow leak is visible by reading
PermissionMatrixEditor.doSave: under the package door it buildsbase = fresh?.effective ?? payloadand thenmerged = { ...base }, so decorations are droppedwhenever the fresh layered read succeeds (
effectiveis a RAW layer) — but the.catch(() => null)arm falls back topayload, which is the decorated draft, and spreads it into the save.That is a failure-path-only leak and it has not been exercised.
Why it is worth a card anyway
The framework has now paid for this class three times (a served
_diagnostics400ing everysaved dataset; the cold-boot flow bind in cloud#971; and objectui#7603 itself). The remaining
value here is that a fourth site is one copy-paste away:
ObjectHooksPanelalready carries ahand-rolled duplicate of the helper objectui#7603 just fixed, so the next author who copies it
inherits the defect and not the cure.
Suggested shape, not a decision
Consider one shared draft-envelope reader that all consumers call, deriving the key list from
the spec's exported
stripReadDecorationsrather than restating it. Triage should decidewhether that is worth the refactor or whether the three sites should simply be measured and
left alone. Not urgent, and expressly not a request to loosen any schema.