Dedupe words: onNavigate react-blocks · ListView action union · new_window · navigation-MODE argument · react-tier catalogue callback type
Surfaced while a domain:ui seat-3 dispatch (objectui#9547) implemented a maintainer ruling in objectstack-ai/objectui, and re-derived here first-hand on this repo's origin/main before filing. ⛔ Not graded, ⛔ no domain:*, ⛔ not routed — that is the triage seat's sole production.
The defect — the react-tier catalogue declares a callback vocabulary the reference implementation contradicts in both directions
packages/spec/src/ui/react-blocks.ts:321, verbatim:
{ name: 'onNavigate', type: "(recordId, action: 'view' | 'edit') => void", kind: 'callback', description: 'Called for page-level navigation.' },
Measured against the implementation that serves it, objectstack-ai/objectui origin/main, packages/react/src/hooks/useNavigationOverlay.ts — every call site of that callback, counted rather than sampled:
| line |
second argument passed |
:314 |
'new_window' |
:323 |
view ?? 'view' |
:337 |
'new_window' |
:356 |
view ?? 'view' |
⭐ Lit control: the same grep over the same file returns 4 call sites, so the instrument is live; the reading below is a real zero, not a failed search.
- branches passing
'edit': 0 — the member the catalogue declares is sent by nothing;
- branches passing
'new_window': 2 — a member the catalogue does not declare at all.
⇒ a host that writes a switch over the declared union handles a case that never fires and silently no-ops on the case that fires on every modifier-click. This is class (b): a declared contract the implementation contradicts, with a named failing probe.
⭐ This repo already ruled on that very argument, one minor version ago
packages/spec/src/ui/view.zod.ts:1815-1822 retires view.list.navigation.view in @objectstack/spec 17.5.0 under ADR-0049, and its text names the slot, verbatim:
the value was passed straight into the navigation-MODE argument of the console's onNavigate, where anything other than edit or view matched no branch, so the key selected nothing and could silently deaden the row click
and the file comment beside it: "an authored name did not select a view, it SUBSTITUTED for the mode" · "Declared, consumed, and wrong: the one state that teaches an author something false."
⇒ the slot is a navigation-MODE token with a closed vocabulary — this repo's own position. The retirement corrected the authored-name substitution. ⛔ It did not correct the vocabulary itself, which still omits new_window and still names edit.
Why it is filed here rather than in the sister repo
基本裁决原则(维护者 2026-09-10,逐字):「我们的项目以objectstack 协议为准,文档应该以实际实现为准。协议不正确的应该先修改协议。」⇒ the wrong union's producer is this catalogue entry; a consumer-side narrowing in objectui would be the shape that ruling refuses.
What is downstream of it, and blocked on it
objectstack-ai/objectui#9547 carries a maintainer ruling (batch #152 item 4 letter 1) that quotes this catalogue entry's union verbatim as the published shape for a new prop. That union does not compile against the hook it must satisfy (TS2322, measured by the delivering dev in both the required and optional spelling), so that card is back in the decision box with this reading on its face.
⚠️ ⛔ Not measured here, and named so nobody reads its absence as clean: whether the literal type string at :321 is pinned by a test in this repo, and whether any consumer outside these two repositories already reads the second argument.
⛔ Not deduped by this seat — the filer attaches the words and triage runs them; a zero needs a lit control, and closed cards are in scope for that search.
Generated by Claude Code
Dedupe words:
onNavigate react-blocks·ListView action union·new_window·navigation-MODE argument·react-tier catalogue callback typeSurfaced while a
domain:uiseat-3 dispatch (objectui#9547) implemented a maintainer ruling inobjectstack-ai/objectui, and re-derived here first-hand on this repo'sorigin/mainbefore filing. ⛔ Not graded, ⛔ nodomain:*, ⛔ not routed — that is the triage seat's sole production.The defect — the react-tier catalogue declares a callback vocabulary the reference implementation contradicts in both directions
packages/spec/src/ui/react-blocks.ts:321, verbatim:Measured against the implementation that serves it,
objectstack-ai/objectuiorigin/main,packages/react/src/hooks/useNavigationOverlay.ts— every call site of that callback, counted rather than sampled::314'new_window':323view ?? 'view':337'new_window':356view ?? 'view'⭐ Lit control: the same grep over the same file returns 4 call sites, so the instrument is live; the reading below is a real zero, not a failed search.
'edit': 0 — the member the catalogue declares is sent by nothing;'new_window': 2 — a member the catalogue does not declare at all.⇒ a host that writes a
switchover the declared union handles a case that never fires and silently no-ops on the case that fires on every modifier-click. This is class (b): a declared contract the implementation contradicts, with a named failing probe.⭐ This repo already ruled on that very argument, one minor version ago
packages/spec/src/ui/view.zod.ts:1815-1822retiresview.list.navigation.viewin@objectstack/spec17.5.0 under ADR-0049, and its text names the slot, verbatim:and the file comment beside it: "an authored name did not select a view, it SUBSTITUTED for the mode" · "Declared, consumed, and wrong: the one state that teaches an author something false."
⇒ the slot is a navigation-MODE token with a closed vocabulary — this repo's own position. The retirement corrected the authored-name substitution. ⛔ It did not correct the vocabulary itself, which still omits
new_windowand still namesedit.Why it is filed here rather than in the sister repo
基本裁决原则(维护者 2026-09-10,逐字):「我们的项目以objectstack 协议为准,文档应该以实际实现为准。协议不正确的应该先修改协议。」⇒ the wrong union's producer is this catalogue entry; a consumer-side narrowing in
objectuiwould be the shape that ruling refuses.What is downstream of it, and blocked on it
objectstack-ai/objectui#9547carries a maintainer ruling (batch #152 item 4 letter 1) that quotes this catalogue entry's union verbatim as the published shape for a new prop. That union does not compile against the hook it must satisfy (TS2322, measured by the delivering dev in both the required and optional spelling), so that card is back in the decision box with this reading on its face.:321is pinned by a test in this repo, and whether any consumer outside these two repositories already reads the second argument.⛔ Not deduped by this seat — the filer attaches the words and triage runs them; a zero needs a lit control, and closed cards are in scope for that search.
Generated by Claude Code