You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Save toast shows the notice a hook or flow attached to the save #28252
Filing gate: ③ the console half of #28000, whose contract half lands in PR #28247 (os-dev-report 6531067088; contract review 6531609713 PASS). ⛔ Not a claim. Triage sets the lane and grade.
Reach: any app whose save sets something in motion the user should hear about (HotCRM: a deal sent for approval on save, #27380 row 3).
The single-record create / update answer carries an optional notice string (info severity, distinct from warnings); @objectstack/client mirrors it. No console surface reads it.
Wanted
The save toast shows notice with, or in place of, the record-named message: AppContent crud_success, RecordFormPage, and the inline edit save. Test plus ablation.
Claim: PM loop round 6 · 2026-10-31T02:48Z
Session: session_01L9qibzC6RxMfB59EsgAoNN (seat; implementation by card thread session session_01L9qibwGdCkvhAHHVnAyVG1, mode:thread)
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-1iw5ln (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-28252
Domain: domain:ui
Seat: domain:ui#1
File surface: ui/packages/react/src/record-save-feedback.ts, ui/packages/app-shell/src/providers/writeWarningToast.ts, AppContent.tsx, RecordFormPage.tsx, the inline-edit save site, ui/packages/plugin-form/src/ObjectFormContainer.tsx, ui/packages/data-objectstack/src/** only if the adapter strips notice, tests, root changeset (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no (the seat's expectation; the dev measures it on the diff, and the seat amends the claim if a new export or a flipped declared surface moves it)
Metadata-protocol: none
Responsibility: the save toast carries the write answer's notice, one toast per write (console half of #28000)
Thread-read: 6533319341
Premise: holds (PR #28247 is on main; no console surface reads notice)
Serial constraints cleared: yes. The p3 hold is lifted for ui by the maintainer: 「可以开p3」, and 2026-10-31T02:39Z 「ui 车道一堆任务啊,应该并发开满啊」 in the seat thread. domain:ui#2 and #4 are off duty.
Order: /mnt/project-files/ui-seat-1/r2026-10-30/dispatch-28252.md under FRAME.md.
{
"issue": 28252,
"status": "done",
"branch": "claude/project-thread-1iw5ln",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28307",
"session": "session_01L9qibwGdCkvhAHHVnAyVG1 (card thread; seat session_01L9qibzC6RxMfB59EsgAoNN)",
"premise_still_valid": true,
"summary": "Measured: the adapter's create/update resolved result.record and read only droppedFields/warnings, so the answer's notice was dropped there. notifyDroppedFields now carries notice (non-empty string) on WriteWarningEvent and emits when it is the only news; resolved values unchanged. The notice rides the existing claim: take() returns RecordSaveFeedback {warnings, notice?}, toastRecordSave titles with the surface's message and puts notice then warnings under it (success variant for a notice alone, warning variant with warnings). Surfaces showing it on their one toast: AppContent crud_success + child-form task, RecordFormPage, ObjectFormContainer drawer/modal, ObjectGrid per-row save and Save All (new claims). Unclaimed writes (incl. the record page InlineEditSaveBar, which has no save toast) get one channel toast: info with the notice, or the notice leading the warnings toast.",
"tests": "head 4056fd97. 8 toast files: 8 passed, 100 tests. Locked run: vitest packages/react/ data-objectstack/ plugin-form/ plugin-grid/ + 130 app-shell/console files naming the touched symbols: VERDICT command-exit 0, Test Files 845 passed, Tests 8464 passed 1 skipped (whole app-shell suite left to CI Test UI). type-check data-objectstack, react, plugin-form, plugin-grid, app-shell exit 0 each. Ablations via ablation-replace.mjs, restored to HEAD blob each: channel parks on warnings only -> 5 notice cells red; adapter drops notice -> 7 red; grid row save without take -> 2 red.",
"gates": "dispatch-gates --commands at 4056fd97: 35 derived, 35 run, all exit 0 (check-sdui-manifest + --self-test, ui vitest scripts/ 169 files passed included; check:type-check-debt first run exit 3 lock queue-timeout NOT MEASURED, re-run under the lock exit 0); --ran reconcile 35/35, 0 NOT-MEASURED, 0 UNRUN, exit 0. Outside the derivation: eslint 14 changed ts/tsx 0 errors; ui check:new-line-citations 0 new, exit 0; turbo build of the closure 64/64 exit 0. CI check-runs on PR 28307: queued/in_progress at report time.",
"line_budget": "+701 / -62, 15 files, under the 3000 human-merge threshold",
"files_changed": [
".changeset/28252-save-toast-hook-notice.md",
"ui/packages/app-shell/src/console/AppContent.tsx",
"ui/packages/app-shell/src/console/__tests__/AppContent.recordSaveOneToast-27999.test.tsx",
"ui/packages/app-shell/src/providers/writeWarningToast.test.ts",
"ui/packages/app-shell/src/providers/writeWarningToast.ts",
"ui/packages/app-shell/src/views/RecordFormPage.saveToastCarriesWarnings-27999.test.tsx",
"ui/packages/app-shell/src/views/RecordFormPage.tsx",
"ui/packages/data-objectstack/src/index.ts",
"ui/packages/data-objectstack/src/onWriteWarning.test.ts",
"ui/packages/plugin-form/src/ObjectFormContainer.tsx",
"ui/packages/plugin-form/src/__tests__/containerSaveToastCarriesWarnings-28216.test.tsx",
"ui/packages/plugin-grid/src/ObjectGrid.tsx",
"ui/packages/plugin-grid/src/__tests__/inlineEditSaveNotice-28252.test.tsx",
"ui/packages/react/src/record-save-feedback.test.ts",
"ui/packages/react/src/record-save-feedback.ts"
],
"deviations": "Clause-2 measured yes (widening): WriteWarningEvent.notice and the new RecordSaveFeedback type; the claim recorded no, so the seat amends it. take()/toastRecordSave signatures changed but those exports are unreleased (#28267 changeset pending). File surface: ui/packages/plugin-grid/src/ObjectGrid.tsx is the inline-edit save site the order names; data-objectstack touched because the adapter stripped notice. Full app-shell suite not run locally (lock time); narrowed to the 130 files naming the touched code, declared here.",
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3: issue_read get x1, issue_read get_comments x2; no write tool",
"api_writes": "2: pr_create via fleet-write relay (run 41167216703, read-back identical 11587 bytes); this comment via post-stamped",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the record page inline-edit Save bar (InlineEditSaveBar) raises no save toast of its own, so its notice reaches the user through the channel's info toast (PR acceptance notes)"
]
}
Claim amendment · 2026-10-31T04:09Z · amends claim 6538004798 after the card thread's os-dev-report 6538812279. Append-only.
Clause-②: yes (widening: @object-ui/data-objectstackWriteWarningEvent gains optional notice, and the event now fires for a notice-only answer; @object-ui/react gains RecordSaveFeedback; no accept set moves)
The dev's measure on PR #28307 replaces the claim's expected no, and the PR goes to the contract-review lane before the seat lands it.
The PR also reshapes two @object-ui/react signatures. AnswerWarningClaim.take() now returns { warnings, notice? } instead of string[], and toastRecordSave's third argument is now Partial<RecordSaveFeedback>. The seat does not count this as a narrowing. Both exports first landed in #28267 (ba5c754d, 2026-10-30T22:36:33Z), their changeset .changeset/28216-form-container-one-save-toast.md is still pending on origin/main, and the published @object-ui/react is still 18.2.0, so no released consumer has seen the old shape. The two changes ship in one release as additive exports. This is called out here so the lane can check it.
The seat accepts one addition to the file surface: ui/packages/plugin-grid/src/ObjectGrid.tsx (the grid's per-row save and Save All), which is the "inline edit save" site the card names.
Seat read on head 4056fd97 found no blockers so far:
The adapter reads notice only as a non-empty string, so an older runtime's answer adds nothing.
A claimed write shows the notice on its one toast, above the warnings. A notice alone keeps the success variant.
An unclaimed write gets one info toast from the channel.
merged 2026-10-31T05:02:36Z as b1e1dcf2 through the merge queue, on the first pass
origin/main content
ui/packages/data-objectstack/src/index.ts reads the answer's notice (readWriteNotice). record-save-feedback.ts carries RecordSaveFeedback, and the save surfaces show the notice on their one toast.
State: Fixes #28252 closes the card as completed. pm:dispatched comes off in the same stroke as this note. The review's condition held: no Version Packages release was cut between #28267 and this PR. The live measure belongs with the server half #28251. Nothing else remains on this card.
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p3 ·
domain:ui·area:records·pm:blockedon #28247 · 2026-10-30T20:01Z⛔ Not a claim.
notice. The parent Save answer: a hook or record-triggered flow can attach one user-facing notice to a record save, shown with the save toast #28000 is p3, so this card is p3 too. Use one toast per write, following the console: what a save or bulk action tells the user: a bulk action reports Succeeded N / N whatever each row did, a warning save shows two toasts, a hook cannot add a sentence to the save toast, and Delete has no per-object confirm text #27380 row 2 rule, and the PR names its surfaces.Blocked-by: #28247is added to the body.pm:blocked.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: unblocked · p3 · 2026-10-30T20:57Z
⛔ Not a claim.
Blocked-by: #28247, and PR feat(spec): a hook can tell the person who saved a record what the save set in motion #28247 merged at 2026-10-30T20:25Z.pm:blockedis removed. It stays at p3 withoutpm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN
Claim: PM loop round 6 · 2026-10-31T02:48Z
Session:
session_01L9qibzC6RxMfB59EsgAoNN(seat; implementation by card thread sessionsession_01L9qibwGdCkvhAHHVnAyVG1,mode:thread)Account:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-1iw5ln(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-28252Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/react/src/record-save-feedback.ts,ui/packages/app-shell/src/providers/writeWarningToast.ts,AppContent.tsx,RecordFormPage.tsx, the inline-edit save site,ui/packages/plugin-form/src/ObjectFormContainer.tsx,ui/packages/data-objectstack/src/**only if the adapter stripsnotice, tests, root changeset (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no (the seat's expectation; the dev measures it on the diff, and the seat amends the claim if a new export or a flipped declared surface moves it)
Metadata-protocol: none
Responsibility: the save toast carries the write answer's
notice, one toast per write (console half of #28000)Thread-read: 6533319341
Premise: holds (PR #28247 is on
main; no console surface readsnotice)Serial constraints cleared: yes. The p3 hold is lifted for ui by the maintainer: 「可以开p3」, and 2026-10-31T02:39Z 「ui 车道一堆任务啊,应该并发开满啊」 in the seat thread.
domain:ui#2and#4are off duty.Order:
/mnt/project-files/ui-seat-1/r2026-10-30/dispatch-28252.mdunderFRAME.md.objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibwGdCkvhAHHVnAyVG1
os-dev-report
{ "issue": 28252, "status": "done", "branch": "claude/project-thread-1iw5ln", "pr": "https://github.com/objectstack-ai/objectstack/pull/28307", "session": "session_01L9qibwGdCkvhAHHVnAyVG1 (card thread; seat session_01L9qibzC6RxMfB59EsgAoNN)", "premise_still_valid": true, "summary": "Measured: the adapter's create/update resolved result.record and read only droppedFields/warnings, so the answer's notice was dropped there. notifyDroppedFields now carries notice (non-empty string) on WriteWarningEvent and emits when it is the only news; resolved values unchanged. The notice rides the existing claim: take() returns RecordSaveFeedback {warnings, notice?}, toastRecordSave titles with the surface's message and puts notice then warnings under it (success variant for a notice alone, warning variant with warnings). Surfaces showing it on their one toast: AppContent crud_success + child-form task, RecordFormPage, ObjectFormContainer drawer/modal, ObjectGrid per-row save and Save All (new claims). Unclaimed writes (incl. the record page InlineEditSaveBar, which has no save toast) get one channel toast: info with the notice, or the notice leading the warnings toast.", "tests": "head 4056fd97. 8 toast files: 8 passed, 100 tests. Locked run: vitest packages/react/ data-objectstack/ plugin-form/ plugin-grid/ + 130 app-shell/console files naming the touched symbols: VERDICT command-exit 0, Test Files 845 passed, Tests 8464 passed 1 skipped (whole app-shell suite left to CI Test UI). type-check data-objectstack, react, plugin-form, plugin-grid, app-shell exit 0 each. Ablations via ablation-replace.mjs, restored to HEAD blob each: channel parks on warnings only -> 5 notice cells red; adapter drops notice -> 7 red; grid row save without take -> 2 red.", "gates": "dispatch-gates --commands at 4056fd97: 35 derived, 35 run, all exit 0 (check-sdui-manifest + --self-test, ui vitest scripts/ 169 files passed included; check:type-check-debt first run exit 3 lock queue-timeout NOT MEASURED, re-run under the lock exit 0); --ran reconcile 35/35, 0 NOT-MEASURED, 0 UNRUN, exit 0. Outside the derivation: eslint 14 changed ts/tsx 0 errors; ui check:new-line-citations 0 new, exit 0; turbo build of the closure 64/64 exit 0. CI check-runs on PR 28307: queued/in_progress at report time.", "line_budget": "+701 / -62, 15 files, under the 3000 human-merge threshold", "files_changed": [ ".changeset/28252-save-toast-hook-notice.md", "ui/packages/app-shell/src/console/AppContent.tsx", "ui/packages/app-shell/src/console/__tests__/AppContent.recordSaveOneToast-27999.test.tsx", "ui/packages/app-shell/src/providers/writeWarningToast.test.ts", "ui/packages/app-shell/src/providers/writeWarningToast.ts", "ui/packages/app-shell/src/views/RecordFormPage.saveToastCarriesWarnings-27999.test.tsx", "ui/packages/app-shell/src/views/RecordFormPage.tsx", "ui/packages/data-objectstack/src/index.ts", "ui/packages/data-objectstack/src/onWriteWarning.test.ts", "ui/packages/plugin-form/src/ObjectFormContainer.tsx", "ui/packages/plugin-form/src/__tests__/containerSaveToastCarriesWarnings-28216.test.tsx", "ui/packages/plugin-grid/src/ObjectGrid.tsx", "ui/packages/plugin-grid/src/__tests__/inlineEditSaveNotice-28252.test.tsx", "ui/packages/react/src/record-save-feedback.test.ts", "ui/packages/react/src/record-save-feedback.ts" ], "deviations": "Clause-2 measured yes (widening): WriteWarningEvent.notice and the new RecordSaveFeedback type; the claim recorded no, so the seat amends it. take()/toastRecordSave signatures changed but those exports are unreleased (#28267 changeset pending). File surface: ui/packages/plugin-grid/src/ObjectGrid.tsx is the inline-edit save site the order names; data-objectstack touched because the adapter stripped notice. Full app-shell suite not run locally (lock time); narrowed to the 130 files naming the touched code, declared here.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "3: issue_read get x1, issue_read get_comments x2; no write tool", "api_writes": "2: pr_create via fleet-write relay (run 41167216703, read-back identical 11587 bytes); this comment via post-stamped", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed: the record page inline-edit Save bar (InlineEditSaveBar) raises no save toast of its own, so its notice reaches the user through the channel's info toast (PR acceptance notes)" ] }objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN
Claim amendment · 2026-10-31T04:09Z · amends claim 6538004798 after the card thread's os-dev-report 6538812279. Append-only.
Clause-②: yes (widening:
@object-ui/data-objectstackWriteWarningEventgains optionalnotice, and the event now fires for a notice-only answer;@object-ui/reactgainsRecordSaveFeedback; no accept set moves)The dev's measure on PR #28307 replaces the claim's expected
no, and the PR goes to the contract-review lane before the seat lands it.The PR also reshapes two
@object-ui/reactsignatures.AnswerWarningClaim.take()now returns{ warnings, notice? }instead ofstring[], andtoastRecordSave's third argument is nowPartial<RecordSaveFeedback>. The seat does not count this as a narrowing. Both exports first landed in #28267 (ba5c754d, 2026-10-30T22:36:33Z), their changeset.changeset/28216-form-container-one-save-toast.mdis still pending onorigin/main, and the published@object-ui/reactis still18.2.0, so no released consumer has seen the old shape. The two changes ship in one release as additive exports. This is called out here so the lane can check it.The seat accepts one addition to the file surface:
ui/packages/plugin-grid/src/ObjectGrid.tsx(the grid's per-row save and Save All), which is the "inline edit save" site the card names.Seat read on head
4056fd97found no blockers so far:noticeonly as a non-empty string, so an older runtime's answer adds nothing.objectstack-fleet commentedon Oct 31, 2026
domain:ui#1 · os-tesla · session_01L9qibzC6RxMfB59EsgAoNN
Landed · 2026-10-31T05:04Z · PR #28307 (seat ACCEPT 6538982635, pinned to
4056fd97; contract-review PASS 6538972595).b1e1dcf2through the merge queue, on the first passorigin/maincontentui/packages/data-objectstack/src/index.tsreads the answer'snotice(readWriteNotice).record-save-feedback.tscarriesRecordSaveFeedback, and the save surfaces show the notice on their one toast.State:
Fixes #28252closes the card as completed.pm:dispatchedcomes off in the same stroke as this note. The review's condition held: no Version Packages release was cut between #28267 and this PR. The live measure belongs with the server half #28251. Nothing else remains on this card.