Filed unassigned by the dev seat implementing #5221 (session 01EuPCi56cnGyykygi3z9w4m, branch claude/issue-5221-onsuccess-navigation, PR #5933). Observation, not a claim on anyone's time — recording a measurement so the next reader does not have to retake it.
Duplicate-checked against the repo-scoped open-issue listing (222 open issues scanned; /search/issues is unavailable in that environment): the only other cards naming this key are #5221 (the console navigation half, now implemented) and #5493 (the four renderer surfaces that drop the key). Neither covers the channel below.
What was measured
packages/core/src/actions/ActionRunner.ts declares a runtime meaning for onSuccess that predates the spec key:
323: onSuccess?: ActionDef | ActionDef[];
read at the end of handlePostExecution and run through executeChain. Two facts about it, both measured on 0fce2ef81:
1 — it is unreachable from validated metadata.@objectstack/spec declares ActionSchema.onSuccess as a closed strict object { navigate: string, openIn: 'self' | 'newTab' }. A callback-shaped value is refused at parse. Against the installed pin:
ActionSchema.safeParse({ …, onSuccess: { navigate: '/x', bogus: 1 } })
→ success: false, issue code: unrecognized_keys
So no author can put an ActionDef there and have it survive publish/save.
2 — it has zero producers in this repo. Every onSuccess: writer outside ActionRunner's own unit test is a React/form callback function on a different surface (plugin-form's ObjectFormSchema.onSuccess?: (data) => void and friends — onSuccess: handleFormSuccess), not an ActionDef. The only two writers of the ActionDef shape are in packages/core/src/actions/__tests__/ActionRunner.test.ts:
1028: onSuccess: { type: 'notify', params: { msg: 'ok' } },
1056: onSuccess: [{ type: 'cb1' }, { type: 'cb2' }],
Why record it
Two meanings now share one key on one runner. PR #5933 tells them apart by the spec's own declaration — a non-array object whose navigate is a string is the spec block, everything else falls through to the callback channel — and pins that the callback channel still runs. That discrimination is sound but it is a standing cost: every future reader of that line has to hold both meanings, and the ADR-0087-style hazard from interpolateTarget's own docblock applies here too — if a spec loosening ever admits a shape closer to an ActionDef, the split becomes ambiguous.
The long-term-correct move is probably to retire the callback channel, leaving onSuccess with exactly the meaning the contract declares. It was deliberately not ridden into #5933:
ActionDef is an exported type of @object-ui/core, so removing a member is a breaking change to the published library, not an internal tidy;- it lands in
packages/core, outside that card's fence; - and a
dead verdict on a runtime channel wants the liveness discipline applied deliberately, not as a rider on a feature PR.
Not asserting a verdict
This is filed as an observation. Whether the channel is genuinely dead, whether a downstream consumer outside this repo uses it, and whether removal is worth a major are all triage questions — the point of the card is that the measurement exists and the two meanings are now documented at the code.
Refs: #5221 · #5933 · #5493
Generated by Claude Code
Filed unassigned by the dev seat implementing #5221 (session
01EuPCi56cnGyykygi3z9w4m, branchclaude/issue-5221-onsuccess-navigation, PR #5933). Observation, not a claim on anyone's time — recording a measurement so the next reader does not have to retake it.Duplicate-checked against the repo-scoped open-issue listing (222 open issues scanned;
/search/issuesis unavailable in that environment): the only other cards naming this key are #5221 (the console navigation half, now implemented) and #5493 (the four renderer surfaces that drop the key). Neither covers the channel below.What was measured
packages/core/src/actions/ActionRunner.tsdeclares a runtime meaning foronSuccessthat predates the spec key:read at the end of
handlePostExecutionand run throughexecuteChain. Two facts about it, both measured on0fce2ef81:1 — it is unreachable from validated metadata.
@objectstack/specdeclaresActionSchema.onSuccessas a closed strict object{ navigate: string, openIn: 'self' | 'newTab' }. A callback-shaped value is refused at parse. Against the installed pin:So no author can put an
ActionDefthere and have it survive publish/save.2 — it has zero producers in this repo. Every
onSuccess:writer outsideActionRunner's own unit test is a React/form callback function on a different surface (plugin-form'sObjectFormSchema.onSuccess?: (data) => voidand friends —onSuccess: handleFormSuccess), not anActionDef. The only two writers of theActionDefshape are inpackages/core/src/actions/__tests__/ActionRunner.test.ts:Why record it
Two meanings now share one key on one runner. PR #5933 tells them apart by the spec's own declaration — a non-array object whose
navigateis a string is the spec block, everything else falls through to the callback channel — and pins that the callback channel still runs. That discrimination is sound but it is a standing cost: every future reader of that line has to hold both meanings, and the ADR-0087-style hazard frominterpolateTarget's own docblock applies here too — if a spec loosening ever admits a shape closer to anActionDef, the split becomes ambiguous.The long-term-correct move is probably to retire the callback channel, leaving
onSuccesswith exactly the meaning the contract declares. It was deliberately not ridden into #5933:ActionDefis an exported type of@object-ui/core, so removing a member is a breaking change to the published library, not an internal tidy;packages/core, outside that card's fence;deadverdict on a runtime channel wants the liveness discipline applied deliberately, not as a rider on a feature PR.Not asserting a verdict
This is filed as an observation. Whether the channel is genuinely dead, whether a downstream consumer outside this repo uses it, and whether removal is worth a major are all triage questions — the point of the card is that the measurement exists and the two meanings are now documented at the code.
Refs: #5221 · #5933 · #5493
Generated by Claude Code