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
Studio publish refusals: shown only as a ~4 s toast with engine-internal text; the Pending changes panel keeps no refusal; "Show me" does not focus the offending input and the dashboard/report refusal strip has no "Show me" #26730
Filing gate: ① product defect, reproduced, landing site named.
Batch-of: studio-qa-2026-10-27 — 39 cards from one Studio QA run (coordinator session session_01J8VVAkZns5rNnK2rtszzbQ; tested at 3fcafcd3; origin/main was 43731031 at filing, so the implementer re-checks the landing site on current main). The run record is the qa-run issue filed with this batch.
Symptom
When publish is refused, the reason vanishes after a few seconds, sometimes reads like source code, and the "Show me" affordance lands the builder near — not on — the problem.
Reproduction
Publish a package with an unconfigured summary field → toast for ~4 s with text like "engine.ts — if (!d.summaryOperations) continue"; Pending changes panel shows no refusal afterwards.
Data refusal strip › "Show me" → the inspector opens but document.activeElement is the body/button, not the field input.
A refused dashboard or report shows a refusal strip without "Show me".
Expected
The refusal stays visible on the item in Pending changes until fixed, uses author-facing text, and "Show me" focuses the offending input for every item kind.
Suspected landing site (the implementer verifies)
StudioDesignSurface.tsx (~1436-1500 publish result handling, ~6411-6424 Show me, ~4641 leaf strip) and DraftChangesPanel.tsx.
Filing facts
reach: Studio UI, measured by the Data, Interfaces and Access QA cards.
Business reason: Refusals are where builders most need guidance; a disappearing, code-shaped message sends them hunting.
Reader who acts: the triage seat (first touch: domain, area, level), then that lane's os-dev implementer. QA suggestion only: domain:ui, area:studio, p3.
p2: publish refusals show only as a ~4 s toast with engine-internal text, the Pending changes panel keeps none, and "Show me" does not focus the input. Keep the refusal in the panel until resolved, in author terms, and focus the field. From the studio-qa-2026-10-27 batch. Re-check the landing site on current main.
Dispatch order · domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-27T22:33Z
You are the os-dev developer agent for exactly ONE card: #26730, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md and ui/AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/26845" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.
Identity and branch: the seat's Claim: comment on this card is your identity; its Branch: line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Dispatch the ui lane" one message with your branch name and wait. Worktree objectstack-issue-26730 on that branch from a fresh origin/main; pnpm install (frozen lockfile); push with git push -u origin <branch> (⛔ no force).
Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array [{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced; --dry-run first); your report comment through node scripts/pm/post-stamped.mjs --comment=26730 --file=F --json run ONCE with output captured to a file (timestamps only as {{NOW}} / {{WAS:…}}). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and one run_rerun_failed through the relay. Report both counts (api_writes with endpoints, mcp_calls with tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, then ## 维护者速读 six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on your diff, run each, record exits before any pipe, reconcile with --ran. Changeset in the root .changeset/ when a published package changes. ⛔ ui/.github/** and the root ci.yml are out of bounds. Hand back: when the PR and report are up, send the seat thread "Dispatch the ui lane" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.
Ruling (cannot be re-ruled)
Triage first grade 6447119250, verbatim: "p2: publish refusals show only as a ~4 s toast with engine-internal text, the Pending changes panel keeps none, and "Show me" does not focus the input. Keep the refusal in the panel until resolved, in author terms, and focus the field. … Re-check the landing site on current main." No maintainer ruling.
On origin/main5ec398dc (after #26845 landed), in ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx:
doPublish (≈L1448) reports a failed[] publish only as toast.error(formatPublishFailures(failed)) (≈L1478 org scope, ≈L1552 package). Nothing keeps failed after the toast, so DraftChangesPanel (ui/packages/app-shell/src/preview/DraftChangesPanel.tsx, props ≈L907) never sees it. The likely fix keeps the last publish's failures in surface state, passes them to the panel, and shows each failure on its entry (type/name). Clear one when that entry is re-saved, leaves the pending list, or a later publish succeeds for it. Measure whether BATCH_ABORTED consequences need their own line; the cause entry is the one the author fixes.
"Engine-internal text": formatPublishFailures (metadataError.ts ≈L79) prints type/name: error plus raw issue lines. StudioRefusal (same file, objectui#11785) already turns a save failure into an author sentence, a target, and the raw text behind "Details". Measure whether a publish failure's issues can go through the same reader, and reuse it rather than adding a third formatter. ⛔ formatMetadataError is not changed. Do not rewrite server text; put it behind Details.
"Show me": strips at ≈L4683 (Interfaces pillar error: no onShow, which covers the dashboard/report case), ≈L6483 (Data, showObjTarget ≈L5589 only selects), and ≈L8130 (Automations). Measure where focus lands after onShow; the likely fix moves focus to the target's input once the inspector has rendered it. Give the Interfaces strip an onShow where its refusal carries a target.
Scope
File surface: StudioDesignSurface.tsx, DraftChangesPanel.tsx, metadataError.ts, the inspectors only where a focus hook is needed, i18n rows in the lazy studio namespace (a zh test preloads with await loadStudioCatalogue('zh')), and tests. Tests: a refused publish leaves the refusal on its Pending changes entry after the toast is gone, worded by the refusal reader, with the raw text under Details; re-saving or a successful publish clears it; "Show me" from Data, Automations and Interfaces (a dashboard or report target) puts document.activeElement on the offending input; a successful publish shows no refusal. Ablation: drop the kept-failures state, then drop the focus move; each turns its tests red. ⛔ No change to publish gating, the held-edit guard, or server text.
Serial: open PR #26920 (another lane, #26708) edits StudioDesignSurface.tsx near L1270–1330 (package not-found), which is disjoint from these regions. #26733 (rail empty-search) runs in parallel on the rail call sites (≈L5104/6341/7969/8892), also disjoint. Whoever lands second merges origin/main.
Tier
No path-derived mandate. TIER_DEFAULT, effort high (M–L). Clause-②: no, Metadata-protocol: none expected. Patch changeset for @object-ui/i18n if you add namespace rows; none for app-shell (private: true).
Claim: PM loop round 5 · 2026-10-27T22:37Z
Session: session_01JQwxbZeBv2y91towxasSUT (seat; implementation by card thread session session_01JQwxbaQ2uD68Bnvz94D9D1, mode:thread)
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-uyrpwg (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
Worktree: objectstack-issue-26730 in the card thread's clone
Domain: domain:ui
Seat: domain:ui#1 (seat post #25966)
File surface: ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, ui/packages/app-shell/src/preview/DraftChangesPanel.tsx, ui/packages/app-shell/src/views/studio-design/metadataError.ts, inspectors only where a focus hook is needed, studio namespace i18n rows (ui/packages/i18n/src/namespaces/studio/{en,zh}.ts) + a patch changeset + tests (stop on breach; explain in the report)
Container & model: M–L, mode:thread (the maintainer's word on the seat thread, 「opus 很多,并发5」), model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: Studio's publish result handling (this lane's code) | the server's refusal is correct; only the surface drops it | a refused publish leaves the author with a 4 s toast and a "Show me" that does not reach the input
Thread-read: 6455247899
Premise: holds — on origin/main5ec398dcdoPublish (≈L1448) reports failed[] only through toast.error(formatPublishFailures(failed)) (≈L1478/L1552) and keeps nothing for DraftChangesPanel; the Interfaces pillar's strip (≈L4683) has no onShow; Data's showObjTarget (≈L5589) only selects.
Serial constraints cleared: #26845 landed (PR #26927, 22:28Z); open PR #26920 (#26708, another lane) edits StudioDesignSurface.tsx ≈L1270–1330, disjoint; #26733 (this seat, rail call sites) runs in parallel on disjoint hunks; seat 5 (#26945) holds the Interfaces pillar cards and keeps away from the refusal strip. Second to land merges origin/main.
Resume-from: none
{
"issue": 26730,
"status": "done",
"branch": "claude/project-thread-uyrpwg",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26994",
"head": "330e5fef",
"session": "session_01JQwxbaQ2uD68Bnvz94D9D1",
"premise_still_valid": true,
"summary": "A refused publish now keeps each causal failure (non-BATCH_ABORTED) on its Pending changes entry via a new DraftChangesPanel renderEntryNote prop, worded by the refused-save reader (new publishRefusal in metadataError.ts, gate paths re-rooted, draft body read back best-effort) with the raw text under Details; a re-save of that draft, a publish that lets it through, or the ledger no longer listing it clears it. The toast names items and points at the sheet with no engine text. Show me in Data, Automations and Interfaces now focuses the named input (useShowInputFocus); Interfaces gains a Show me via dashboard-widget and report locators. en/zh rows in the studio namespace, patch changeset for @object-ui/i18n.",
"tests": "7 new/updated files: Test Files 7 passed (7), Tests 26 passed (26). Full studio-design + preview at head: Test Files 274 passed (274), Tests 1950 passed (1950), lock VERDICT command-exit 0. i18n: tsc exit 0, Test Files 89 passed (89), Tests 1373 passed, 13 skipped. app-shell tsc --noEmit and tsc -p tsconfig.test.json exit 0; eslint touched files 0 errors. Ablation 1 (delete setPublishRefusals(new Map(...)) in doPublish): publishRefusal-26730 surface test 3 failed, 1 passed (control); restored blob == HEAD. Ablation 2 (delete control.focus() in useShowInputFocus): 3 showMeFocus files, 6 of 6 failed; restored blob == HEAD. Both via scripts/ablation-replace.mjs with a git checkout HEAD trap.",
"gates": "dispatch-gates --commands derived 34; all 34 ran with exit codes recorded before any pipe, all exit 0; --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. The run was interrupted once by a container restart after gate 5 and resumed from gate 6. CI check-runs: pending at report time. Lines: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 | node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 | node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 | node scripts/check-closing-keyword-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 | node scripts/check-comment-mask-corpus.mjs :: exit 0 | node scripts/check-empty-changeset.mjs --base origin/main :: exit 0 | node scripts/check-empty-changeset.mjs --self-test :: exit 0 | node scripts/check-sdui-manifest.mjs :: exit 0 | node scripts/check-sdui-manifest.mjs --self-test :: exit 0 | node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 | node scripts/release-pending-publish.mjs --self-test :: exit 0 | pnpm --dir ui exec vitest run scripts/ :: exit 0 | pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 | pnpm check:changeset-gate-self-tests :: exit 0 | pnpm check:closed-ceremony-text :: exit 0 | pnpm check:cross-package-test-inputs :: exit 0 | pnpm check:dispatcher-error-vocabulary :: exit 0 | pnpm check:driver-memory-census :: exit 0 | pnpm check:engine-double-contract :: exit 0 | pnpm check:gitlink-declared :: exit 0 | pnpm check:nul-bytes :: exit 0 | pnpm check:pm-changeset-deadline-census :: exit 0 | pnpm check:published-files :: exit 0 | pnpm check:query-options-erasure :: exit 0 | pnpm check:refd-timer-probe :: exit 0 | pnpm check:skill-identifier-liveness :: exit 0 | pnpm check:test-source-alias :: exit 0 | pnpm check:tier-file-adoption :: exit 0 | pnpm check:type-check-coverage :: exit 0 | pnpm check:type-check-debt :: exit 0 | pnpm check:undeclared-dep-imports :: exit 0 | pnpm check:watch-hint-literal :: exit 0 | pnpm check:where-matcher :: exit 0",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no GitHub MCP tool called, read or write",
"api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create, run 40608805901, read-back 10732 bytes sent = stored) and this report via scripts/pm/post-stamped.mjs (relay issue comment on #26730); plus git push of the thread branch",
"open_questions": [],
"acceptance_notes": [
"The Pending changes note has no Show me: the sheet's deep-link channel only opens objects; the pillar strips carry it.",
"Held edits keep their behaviour.",
"Refusals key on canonical type and name; bundle members (email_template pairs) share one note.",
"BATCH_ABORTED siblings get no note; the toast says the batch waits.",
"An issue-less failure reads Not published: REASON with the server text unchanged.",
"StudioDesignSurface.publishCount-11807.test.tsx updated: toast title is now the count sentence, item and reason in the description.",
"No change to publish gating, the held-edit guard, server text, formatMetadataError or formatPublishFailures.",
"PR body folds the PULL_REQUEST_TEMPLATE headings into the os-dev order (os-dev exception)."
],
"out_of_scope_findings": []
}
PR #26994 merged as a8ee8a229a (seat record: PR comment 6457550459). A refused publish no longer lives only in a short toast. Each refused draft's reason now stays under its entry in Pending changes, in author terms, with the raw text behind Details. It clears when the item is saved again, published, or gone. "Show me" lands on the offending input in the Data, Automations and Interfaces pillars, and dashboard widgets and reports gained a locator too. pm:dispatched is removed with the close.
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: first grade —
priority:p2·domain:ui·area:studio·pm:queue(findingremoved) · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T16:11Z⛔ Not a claim, ⛔ not a dispatch.
main.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Dispatch order ·
domain:ui#1·session_01JQwxbZeBv2y91towxasSUT· 2026-10-27T22:33ZYou are the os-dev developer agent for exactly ONE card: #26730, in your own card thread. Your role definition is
.claude/agents/os-dev.mdin the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-rootAGENTS.mdandui/AGENTS.mdbefore your first edit, and pm-dispatchreferences/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/26845" -H "Authorization: Bearer $GH_TOKEN"and/comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with[ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.Identity and branch: the seat's
Claim:comment on this card is your identity; itsBranch:line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWESTClaim:on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Dispatch the ui lane" one message with your branch name and wait. Worktreeobjectstack-issue-26730on that branch from a freshorigin/main;pnpm install(frozen lockfile); push withgit push -u origin <branch>(⛔ no force).Writes: PR only through the relay op
pr_create(node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array[{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced;--dry-runfirst); your report comment throughnode scripts/pm/post-stamped.mjs --comment=26730 --file=F --jsonrun ONCE with output captured to a file (timestamps only as{{NOW}}/{{WAS:…}}). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and onerun_rerun_failedthrough the relay. Report both counts (api_writeswith endpoints,mcp_callswith tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, then## 维护者速读six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon your diff, run each, record exits before any pipe, reconcile with--ran. Changeset in the root.changeset/when a published package changes. ⛔ui/.github/**and the rootci.ymlare out of bounds. Hand back: when the PR and report are up, send the seat thread "Dispatch the ui lane" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.Ruling (cannot be re-ruled)
Triage first grade 6447119250, verbatim: "p2: publish refusals show only as a ~4 s toast with engine-internal text, the Pending changes panel keeps none, and "Show me" does not focus the input. Keep the refusal in the panel until resolved, in author terms, and focus the field. … Re-check the landing site on current
main." No maintainer ruling.PM mechanism assumptions (measure; disproof welcome)
On
origin/main5ec398dc(after #26845 landed), inui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx:doPublish(≈L1448) reports afailed[]publish only astoast.error(formatPublishFailures(failed))(≈L1478 org scope, ≈L1552 package). Nothing keepsfailedafter the toast, soDraftChangesPanel(ui/packages/app-shell/src/preview/DraftChangesPanel.tsx, props ≈L907) never sees it. The likely fix keeps the last publish's failures in surface state, passes them to the panel, and shows each failure on its entry (type/name). Clear one when that entry is re-saved, leaves the pending list, or a later publish succeeds for it. Measure whetherBATCH_ABORTEDconsequences need their own line; the cause entry is the one the author fixes.formatPublishFailures(metadataError.ts≈L79) printstype/name: errorplus raw issue lines.StudioRefusal(same file, objectui#11785) already turns a save failure into an author sentence, a target, and the raw text behind "Details". Measure whether a publish failure'sissuescan go through the same reader, and reuse it rather than adding a third formatter. ⛔formatMetadataErroris not changed. Do not rewrite server text; put it behind Details.error: noonShow, which covers the dashboard/report case), ≈L6483 (Data,showObjTarget≈L5589 only selects), and ≈L8130 (Automations). Measure where focus lands afteronShow; the likely fix moves focus to the target's input once the inspector has rendered it. Give the Interfaces strip anonShowwhere its refusal carries a target.Scope
File surface:
StudioDesignSurface.tsx,DraftChangesPanel.tsx,metadataError.ts, the inspectors only where a focus hook is needed, i18n rows in the lazystudionamespace (a zh test preloads withawait loadStudioCatalogue('zh')), and tests. Tests: a refused publish leaves the refusal on its Pending changes entry after the toast is gone, worded by the refusal reader, with the raw text under Details; re-saving or a successful publish clears it; "Show me" from Data, Automations and Interfaces (a dashboard or report target) putsdocument.activeElementon the offending input; a successful publish shows no refusal. Ablation: drop the kept-failures state, then drop the focus move; each turns its tests red. ⛔ No change to publish gating, the held-edit guard, or server text.Serial: open PR #26920 (another lane, #26708) edits
StudioDesignSurface.tsxnear L1270–1330 (package not-found), which is disjoint from these regions. #26733 (rail empty-search) runs in parallel on the rail call sites (≈L5104/6341/7969/8892), also disjoint. Whoever lands second mergesorigin/main.Tier
No path-derived mandate.
TIER_DEFAULT, efforthigh(M–L).Clause-②: no,Metadata-protocol: noneexpected. Patch changeset for@object-ui/i18nif you add namespace rows; none for app-shell (private: true).objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 5 · 2026-10-27T22:37Z
Session:
session_01JQwxbZeBv2y91towxasSUT(seat; implementation by card thread sessionsession_01JQwxbaQ2uD68Bnvz94D9D1,mode:thread)Account:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-uyrpwg(the card thread's harness push branch, self-reported — the measured platform exception toclaude/issue-N-slug)Worktree:
objectstack-issue-26730in the card thread's cloneDomain:
domain:uiSeat:
domain:ui#1(seat post #25966)File surface:
ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx,ui/packages/app-shell/src/preview/DraftChangesPanel.tsx,ui/packages/app-shell/src/views/studio-design/metadataError.ts, inspectors only where a focus hook is needed, studio namespace i18n rows (ui/packages/i18n/src/namespaces/studio/{en,zh}.ts) + a patch changeset + tests (stop on breach; explain in the report)Container & model:
M–L,mode:thread(the maintainer's word on the seat thread, 「opus 很多,并发5」),model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: Studio's publish result handling (this lane's code) | the server's refusal is correct; only the surface drops it | a refused publish leaves the author with a 4 s toast and a "Show me" that does not reach the input
Thread-read: 6455247899
Premise: holds — on
origin/main5ec398dcdoPublish(≈L1448) reportsfailed[]only throughtoast.error(formatPublishFailures(failed))(≈L1478/L1552) and keeps nothing forDraftChangesPanel; the Interfaces pillar's strip (≈L4683) has noonShow; Data'sshowObjTarget(≈L5589) only selects.Serial constraints cleared: #26845 landed (PR #26927, 22:28Z); open PR #26920 (#26708, another lane) edits
StudioDesignSurface.tsx≈L1270–1330, disjoint; #26733 (this seat, rail call sites) runs in parallel on disjoint hunks; seat 5 (#26945) holds the Interfaces pillar cards and keeps away from the refusal strip. Second to land mergesorigin/main.Resume-from: none
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 26730, "status": "done", "branch": "claude/project-thread-uyrpwg", "pr": "https://github.com/objectstack-ai/objectstack/pull/26994", "head": "330e5fef", "session": "session_01JQwxbaQ2uD68Bnvz94D9D1", "premise_still_valid": true, "summary": "A refused publish now keeps each causal failure (non-BATCH_ABORTED) on its Pending changes entry via a new DraftChangesPanel renderEntryNote prop, worded by the refused-save reader (new publishRefusal in metadataError.ts, gate paths re-rooted, draft body read back best-effort) with the raw text under Details; a re-save of that draft, a publish that lets it through, or the ledger no longer listing it clears it. The toast names items and points at the sheet with no engine text. Show me in Data, Automations and Interfaces now focuses the named input (useShowInputFocus); Interfaces gains a Show me via dashboard-widget and report locators. en/zh rows in the studio namespace, patch changeset for @object-ui/i18n.", "tests": "7 new/updated files: Test Files 7 passed (7), Tests 26 passed (26). Full studio-design + preview at head: Test Files 274 passed (274), Tests 1950 passed (1950), lock VERDICT command-exit 0. i18n: tsc exit 0, Test Files 89 passed (89), Tests 1373 passed, 13 skipped. app-shell tsc --noEmit and tsc -p tsconfig.test.json exit 0; eslint touched files 0 errors. Ablation 1 (delete setPublishRefusals(new Map(...)) in doPublish): publishRefusal-26730 surface test 3 failed, 1 passed (control); restored blob == HEAD. Ablation 2 (delete control.focus() in useShowInputFocus): 3 showMeFocus files, 6 of 6 failed; restored blob == HEAD. Both via scripts/ablation-replace.mjs with a git checkout HEAD trap.", "gates": "dispatch-gates --commands derived 34; all 34 ran with exit codes recorded before any pipe, all exit 0; --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. The run was interrupted once by a container restart after gate 5 and resumed from gate 6. CI check-runs: pending at report time. Lines: node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 | node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 | node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 | node scripts/check-closing-keyword-parity.mjs :: exit 0 | node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 | node scripts/check-comment-mask-corpus.mjs :: exit 0 | node scripts/check-empty-changeset.mjs --base origin/main :: exit 0 | node scripts/check-empty-changeset.mjs --self-test :: exit 0 | node scripts/check-sdui-manifest.mjs :: exit 0 | node scripts/check-sdui-manifest.mjs --self-test :: exit 0 | node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 | node scripts/release-pending-publish.mjs --self-test :: exit 0 | pnpm --dir ui exec vitest run scripts/ :: exit 0 | pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 | pnpm check:changeset-gate-self-tests :: exit 0 | pnpm check:closed-ceremony-text :: exit 0 | pnpm check:cross-package-test-inputs :: exit 0 | pnpm check:dispatcher-error-vocabulary :: exit 0 | pnpm check:driver-memory-census :: exit 0 | pnpm check:engine-double-contract :: exit 0 | pnpm check:gitlink-declared :: exit 0 | pnpm check:nul-bytes :: exit 0 | pnpm check:pm-changeset-deadline-census :: exit 0 | pnpm check:published-files :: exit 0 | pnpm check:query-options-erasure :: exit 0 | pnpm check:refd-timer-probe :: exit 0 | pnpm check:skill-identifier-liveness :: exit 0 | pnpm check:test-source-alias :: exit 0 | pnpm check:tier-file-adoption :: exit 0 | pnpm check:type-check-coverage :: exit 0 | pnpm check:type-check-debt :: exit 0 | pnpm check:undeclared-dep-imports :: exit 0 | pnpm check:watch-hint-literal :: exit 0 | pnpm check:where-matcher :: exit 0", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0 — no GitHub MCP tool called, read or write", "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create, run 40608805901, read-back 10732 bytes sent = stored) and this report via scripts/pm/post-stamped.mjs (relay issue comment on #26730); plus git push of the thread branch", "open_questions": [], "acceptance_notes": [ "The Pending changes note has no Show me: the sheet's deep-link channel only opens objects; the pillar strips carry it.", "Held edits keep their behaviour.", "Refusals key on canonical type and name; bundle members (email_template pairs) share one note.", "BATCH_ABORTED siblings get no note; the toast says the batch waits.", "An issue-less failure reads Not published: REASON with the server text unchanged.", "StudioDesignSurface.publishCount-11807.test.tsx updated: toast title is now the count sentence, item and reason in the description.", "No change to publish gating, the held-edit guard, server text, formatMetadataError or formatPublishFailures.", "PR body folds the PULL_REQUEST_TEMPLATE headings into the os-dev order (os-dev exception)." ], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Landed · seat
domain:ui#1·session_01JQwxbZeBv2y91towxasSUT· 2026-10-28T01:13ZPR #26994 merged as
a8ee8a229a(seat record: PR comment 6457550459). A refused publish no longer lives only in a short toast. Each refused draft's reason now stays under its entry in Pending changes, in author terms, with the raw text behind Details. It clears when the item is saved again, published, or gone. "Show me" lands on the offending input in the Data, Automations and Interfaces pillars, and dashboard widgets and reports gained a locator too.pm:dispatchedis removed with the close.Generated by Claude Code