Observation recorded while executing #5835 (type RecordDetailView's confirm handler as the published ConfirmationHandler + pin that both runtimes feed ActionConfirmDialog the same fields). Filed unassigned, observation-class — nothing user-reachable is known to be broken. Out of #5835's fence, which is the OPEN path; this is the CLOSE path.
Verified on origin/main @ 53dc89db8.
The two runtimes agree on open and disagree on close
Both mount ActionConfirmDialog and both hand it the same field set when it opens — { open, message, options, resolve }. That parity is now pinned by packages/app-shell/src/views/RecordDetailView.confirmRuntimeParity-5835.test.tsx.
Their onOpenChange handlers differ:
packages/app-shell/src/hooks/useConsoleActionRuntime.tsx — replaces the whole state: setConfirmState({ open: false, message: '' }). message is blanked, and options / resolve are dropped.packages/app-shell/src/views/RecordDetailView.tsx — spreads and flips one flag: setConfirmState(s => ({ ...s, open: false })). message, options and resolve are all retained.
Why it may matter, and why it is filed rather than fixed
Two observable consequences, neither confirmed against a running app:
- A blank frame during the close animation.
ActionConfirmDialog renders state.message into AlertDialogDescription and keeps rendering during Radix's exit transition. The console runtime clears message synchronously on close, so the description can go empty while the dialog is still fading; RecordDetailView's copy fades out with its text intact. - A retained
resolve.RecordDetailView keeps the previous promise's resolve in state after close. It is not a correctness bug today — ActionConfirmDialog calls state.resolve?.(false) itself before onOpenChange(false), so the promise is already settled and a second call would be a no-op — but it leaves a stale closure reachable in state, and the two runtimes disagree about whether that is intended.
Neither runtime is obviously the correct one; picking a winner is a call, not a cleanup, which is why this is filed instead of fixed. Same drift family as #5610 and #3320 — RecordDetailView re-implementing a shared runtime and then diverging from it with nothing red in between.
Not a request to merge the two runtimes; #5835's triage ruled that a larger refactor and out of scope.
Generated by Claude Code
Observation recorded while executing #5835 (type
RecordDetailView's confirm handler as the publishedConfirmationHandler+ pin that both runtimes feedActionConfirmDialogthe same fields). Filed unassigned, observation-class — nothing user-reachable is known to be broken. Out of #5835's fence, which is the OPEN path; this is the CLOSE path.Verified on
origin/main@53dc89db8.The two runtimes agree on open and disagree on close
Both mount
ActionConfirmDialogand both hand it the same field set when it opens —{ open, message, options, resolve }. That parity is now pinned bypackages/app-shell/src/views/RecordDetailView.confirmRuntimeParity-5835.test.tsx.Their
onOpenChangehandlers differ:packages/app-shell/src/hooks/useConsoleActionRuntime.tsx— replaces the whole state:setConfirmState({ open: false, message: '' }).messageis blanked, andoptions/resolveare dropped.packages/app-shell/src/views/RecordDetailView.tsx— spreads and flips one flag:setConfirmState(s => ({ ...s, open: false })).message,optionsandresolveare all retained.Why it may matter, and why it is filed rather than fixed
Two observable consequences, neither confirmed against a running app:
ActionConfirmDialogrendersstate.messageintoAlertDialogDescriptionand keeps rendering during Radix's exit transition. The console runtime clearsmessagesynchronously on close, so the description can go empty while the dialog is still fading;RecordDetailView's copy fades out with its text intact.resolve.RecordDetailViewkeeps the previous promise'sresolvein state after close. It is not a correctness bug today —ActionConfirmDialogcallsstate.resolve?.(false)itself beforeonOpenChange(false), so the promise is already settled and a second call would be a no-op — but it leaves a stale closure reachable in state, and the two runtimes disagree about whether that is intended.Neither runtime is obviously the correct one; picking a winner is a call, not a cleanup, which is why this is filed instead of fixed. Same drift family as #5610 and #3320 —
RecordDetailViewre-implementing a shared runtime and then diverging from it with nothing red in between.Not a request to merge the two runtimes; #5835's triage ruled that a larger refactor and out of scope.
Generated by Claude Code