qa(checklist): a hook-refused script action shows exactly one error toast carrying its sentence — item, showcase fixture, and one run - #21609
Merged
objectstack-fleet[bot] merged 4 commits intoOct 3, 2026
Conversation
…e script action that reaches it Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv Co-authored-by: Claude <noreply@anthropic.com>
…ror toast; hook-lifecycle item names the new fixture Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv Co-authored-by: Claude <noreply@anthropic.com>
… only The Task Detail page is kind 'full' and draws no record_header bar, so that declared location was inert; the checklist item now drives the row menu. Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 3, 2026
objectstack-fleet
Bot
deleted the
claude/issue-21596-hook-refusal-toast-item
branch
October 3, 2026 17:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #21596
Clause-②: no
What this does
Gives objectui#9151's re-observation a home: one platform-checklist item, the smallest showcase fixture it needs, and one recorded run of it against a console built at this repo's
.objectui-sha.Run verdict: PASS (1/1 item, 4/4 clauses, reproduced on two finished tasks on fresh page loads). The console showed exactly one
errortoast carrying the hook's sentence, tied to a400from the action route, and the record was left unchanged.The fixture (measured absent, so added)
examples/app-showcasehad no hook that refuses a write.src/data/hooks/index.tsheld four hooks: trim, stamp, and two log-only after-hooks, none of which throw. Added:showcase_guard_task_reopen(src/data/hooks/index.ts,GuardTaskReopenHook): abeforeUpdatehook onshowcase_task. Its condition isprevious.done == true && record.done != trueand its sandboxed body throwsTASK_REOPEN_REFUSAL= "A finished task cannot be reopened. Create a follow-up task instead." withonError: 'abort'.showcase_reopen_task(src/ui/actions/index.ts,ReopenTaskAction): ascriptaction,perRecord, offered only on finished tasks. It appears in the task list's row menu only (list_item). The Task Detail page iskind: 'full'and draws norecord_headerbar, so declaring that location would have been inert. Its body writes{ id, done: false }throughctx.api.check:i18n-coverageratchet).test/task-reopen-hook-refusal.test.ts(5 tests). It uses the production harness: realObjectQL,SqlDriverandQuickJSScriptRunner, with the app's real objects and hooks. The tests check four things. The reopening write is refused with the sentence and the row is unchanged. An edit of a finished task that leavesdonealone still lands. With the hooks unbound, the same write lands (reverse check). The action body writes exactly the refused shape.The checklist item
docs/qa/platform-checklist/areas/records-forms.json, idrecords-forms.script-action-hook-refusal-toast(revision 1, P2, browser). It sits in records-forms, beside the area's action-surface items (action-location-matrix,action-param-widgets,object-hook-lifecycle). It has four clauses:data-type=error, containing the sentence. It is counted inside sonner's 4s auto-dismiss window, excludingdata-removednodes.It is mapped under
actionandhookincoverage.json.records-forms.object-hook-lifecyclewas bumped from revision 2 to 3, roster only, with no clause moved. Two of its knownGaps became false once the fifth hook landed: "no two showcase hooks share an object+event" and "the fixtures never throw". Both now name the new hook and say why it does not close that item's ordering clause or its beforeInsert abort-rollback clause.pnpm check:platform-checklistpasses with exit 0: 15 areas, 270 items, coverage 39 kinds mapped and 2 waived, symbol anchors 650/660.The run
qa-runissue, RUNNER's record of this run).docs/qa/platform-checklist/runs/2026-10-03-script-action-hook-refusal-toast.json. RUNNER's location; git-ignored, so it is not in this diff. Theqa-runissue body is in the report comment on qa(checklist): a script action refused by a hook with a user-facing sentence shows exactly one error toast carrying it — the re-observation objectui#9151 has had no home for since 2026-09-14 #21596.4a428c11a0(the tree served), objectui pin89cad75d55702cc4f267bead5bf267de575d5842. The console was built bypnpm objectui:build(exit 0, stamped objectui@89cad75d5570). The server was an isolatedobjectstack dev --ui --seed-adminon its own port with its own file DB. Driven by Playwright through/opt/pw-browsers/chromium, signed in through the form as the seeded admin.POST /api/v1/actions/showcase_task/showcase_reopen_taskwith status400 VALIDATION_ERROR, message "hook 'showcase_guard_task_reopen' threw: Error: A finished task cannot be reopened. Create a follow-up task instead."data-type=error, same text). A MutationObserver installed before the click saw exactly one toast node added in the following 6s.done,progressandupdated_atwere identical before and after.Acceptance notes
PATCH /api/v1/data/showcase_task/IDanswers400with the bare sentence. The wrapper is whatpackages/qa/dogfood/test/hook-error-format.dogfood.test.tssays belongs in server logs, not in the toast. This is reported to the PM in the report and is not fixed here: no runtime change is in scope.@objectstack/example-showcase, which is"private": true. Its earlier showcase-only fixes (393ae878d3,99398542b3) also carried none.docs/qa/**does not publish.skip-changesetapplies.Verification (head
ff3d71c7cf)pnpm --filter @objectstack/example-showcase run typecheckpassed (exit 0);--listFilesincludes the new test.pnpm --filter @objectstack/example-showcase exec vitest run --maxWorkers=2: 32 files and 399 tests passed.node scripts/pm/dispatch-gates.mjs --commandsderived 45 commands; all 45 exited 0.--ranreconciliation: 45 derived, 45 run, 0 unrun.Generated by Claude Code