Repository navigation
studio: refusal text written for developers (class names, tracker ids, raw Zod paths, spec docstrings) is shown verbatim to authors #11785
Description
Filing gate ① — product defect with a named location and a reproduction. reach: Studio Data pillar: switching a field's type to Picklist shows the red banner quoted below to the author, verbatim.
Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
Text written for developers reaches low-code authors unchanged:
- "MetadataClient.save refused this object metadata write: the field
statusis aselectwith no options … or a sharedpicklist(objectstack#20827), so this draft stays here until it has one." - "…
@objectstack/specrefuses the same document at the server with a 422 onfields.technician.reference… (objectui#7714)." - Raw Zod paths as banners: "nodes.2.config.title — …", "navigation.1.objectName — Invalid input …".
- Spec
.describe()docstrings rendered as form help (the notify node's Template help ends "(maintainer ruling 2026-09-01). A producer-set payload.locale is not consulted."); the action Description help ends "(one dialog, not two —)" with a dangling dash.
Where it comes from (read in source)
assertObjectMetadataWritable in data-objectstack/src/object-metadata-write-guard.ts builds the first two messages (class name, tracker ids, wire paths); formatMetadataError passes server issue paths through; inspectors render spec descriptions as help. The spec-side strings are objectstack-ai/objectstack#22093.
Expected
An author-facing sentence attached to the input it is about, with the technical detail (path, code, ids) behind a disclosure.
Suggested direction (triage to rule)
Split every refusal into {authorMessage, fieldPath, detail}; map Zod paths to the inspector field; keep tracker ids out of runtime strings (the rule objectstack's AGENTS.md already applies to its own runtime prose).
Environment
objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.
Duplicate check
- Semantic issue search on objectstack-ai/objectui (open and closed), developer facing error message MetadataClient.save refused tracker id zod path author: 1 hits (0 open, 1 closed).
- Semantic issue search on objectstack-ai/objectui (open and closed), studio save error banner shows raw internal message issue number class name to author: 2 hits (1 open, 1 closed).
- Semantic issue search on objectstack-ai/objectstack (open and closed), metadata save refusal message names internal class and zod path shown to Studio author: 0 hits (0 open, 0 closed).
- Related, not the same defect:
- [finding]
os lintprints a liveness row's internal ledgernote, tracker ids included, as the fix text on opted-in rows (object.externalSharingModelcites #2696 on app-showcase) objectstack#21096 (closed) — same 'no tracker ids in author-visible text' rule (AGENTS.md), different surface (CLI lint)
- [finding]
- Positive control in the same run: related lists action id refusal notice shown to end users on objectstack-ai/objectui returned related lists: an action id the related object does not define draws a refusal notice above the list for whoever opens the record — an authoring fault shown to end users; scope it to authors/admins #11768: yes.
Dedupe words: developer facing error author · MetadataClient.save refused banner · raw zod path banner · describe docstring as help text
Filed by Claude Code (session session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 7, 2026
Path: ③ 验证:响亮拒绝错的,放行对的 — the author reads a refusal they can act on | 缺项 | P2
Triage: first grade,
bug·priority:p2·domain:ui·area:studio·pm:queue. Direction: Studio shows an author message, a located field path, and a collapsible detailTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T16:16Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in Studio's refusal banners (the autosave and publish error surfaces) ⇒
domain:ui; rationale: a Studio or console surface in objectui. Filed from the Studio browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9).Clause-②: no. Patch changeset in objectui.objectstack-fleet commentedon Oct 7, 2026
Claim: PM loop round 3
Session:
session_01CGZy1BGCjdN5cXqL9cnvB8Account:
os-support-aiBranch:
claude/issue-11785-author-refusal-textWorktree:
objectui-issue-11785Domain:
domain:uiSeat:
domain:ui#3File surface (on
16cda0b):packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx(the autosave and publish error strips that renderformatMetadataError(e), about:481–:487,:697–:702,:785, and the pillars' save-error strips);packages/app-shell/src/views/studio-design/metadataError.ts(itsPublishFailuregrammar);packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx's save-error strip, if it renders the same text;packages/data-objectstack/src/object-metadata-write-guard.ts(assertObjectMetadataWritable,:223): tracker ids and class names out of its runtime strings;packages/app-shell/src/views/metadata-admin/i18n.ts;.changeset/11785-*.md.⛔ Not on it:
formatMetadataError(data-objectstack/src/metadata-error.ts): its return value for its 19 other call sites stays as it is;.describe()help text: the server half, spec: author-visible describe/refusal strings carry internal references (II18nService.getDefaultLocale(), a ruling date, manifest.id, com.steedos.crm) objectstack#22093;ObjectFieldInspector.tsx,FlowReferenceField.tsx,flow-node-config.ts).Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report)
Container & model:
L,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate; default tier).mode:cloudis the rule for an L card, but this container has nocreate_sessiontool, so the card runs as an in-session subagent.Clause-②: no
Responsibility:
objectui app-shell + data-objectstack: Studio's autosave and publish banners print formatMetadataError(e) verbatim, which carries assertObjectMetadataWritable's developer prose (MetadataClient.save, objectstack#20827, objectui#7714, wire paths) and raw Zod issue paths (nodes.2.config.title, navigation.1.objectName) | the platform path: the refusal reaches the client as a structured error (issues with paths), so an author sentence plus a located field plus a collapsible detail can be built client-side | every low-code author whose Studio save or publish is refused (measured: switching a field to Picklist prints the guard's developer text)Thread-read: 6041997331
Serial constraints cleared:
noneblocking. Noarea:studiocard of this seat is in flight. Seat 1's objectui#11783 (area:studio, in flight) holds the files named above, which are disjoint.Fold-or-serial with objectui#11786 (
pm:queue, the autosave refusing normal intermediate states; same autosave path and the same guard): serial, not folded. Fold gate ① fails: wording versus timing are different defect shapes. objectui#11786 waits for this card.No open objectui PR touches the files above (read 2026-10-07T23:39Z; open: #11837, #11836, #11600, #11069).
Why
Clause-②: no: author-facing text and a Studio-side split of refusals inside@object-ui/app-shell, plus message-text edits in@object-ui/data-objectstack's guard. Its error type and exports are unchanged. A new export, prop or type member (for example a structured refusal type exported fromdata-objectstack), or a language-pack key, is a stop: the dev reports it before opening the PR, and the seat amends this line.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{
"issue": 11785,
"status": "done",
"branch": "claude/issue-11785-author-refusal-text",
"pr": "#11848",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8",
"premise_still_valid": true,
"summary": "Studio's Data, Automations and Interfaces save strips now render a StudioRefusal (studio-design/metadataError.ts): one author sentence naming the input in the editor's terms (field label; step label + inspector input via fieldsForNodeType/localizeFlowFields; nav item + Label/Link-to-object), a 'Show me' button that opens it, and the raw formatMetadataError(e) text behind a closed Details disclosure; unmappable paths keep their line under Details. The write guard's message drops the door label, @objectstack/spec and tracker ids (meaning, field/type names and remedy kept; signature, error type and exports unchanged; third param spelled _writer for noUnusedParameters), which makes the message a function of the body alone, so Studio identifies a guard refusal by re-running the guard on the body it sent and requiring byte-identical messages, never by parsing prose. formatMetadataError is untouched. One merge prerequisite is OFF the claim's file surface and was left untouched: packages/data-objectstack/README.md (published) quotes the old guard prefix 'MetadataClient.save refused this object metadata write' twice; this PR makes those quotes false (see open_questions).",
"tests": "All on final commit 36165fc (branch merged with main 455c646, never rebased), under os-verify-lock, from the worktree root. turbo run build --filter=@object-ui/app-shell^... --concurrency=2: 28/28 tasks, exit 0. pnpm --filter @object-ui/data-objectstack type-check (tsc --noEmit): exit 0. pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json, which includes src//.test.ts(x)): exit 0. pnpm exec vitest run on the union (packages/data-objectstack/ in full; packages/app-shell/src/views/studio-design/ in full; 33 app-shell/console tests that import StudioDesignSurface, metadataError, the guard or read the designer table, derived by git grep; write-doors and i18n script tests; all 11 plugin-designer MetadataFieldsPage suites as the non-Studio formatMetadataError control): 'Test Files 228 passed (228)', 'Tests 2608 passed (2608)', exit 0. New pins: metadataError.authorRefusal-11785.test.ts (view model, incl. controls: same words with a server status, guard words about a body not sent, transport failure, formatMetadataError unchanged), DataPillar.authorRefusal-11785.test.tsx (real MetadataClient door: Picklist with no options shows tFormat('engine.studio.refusal.choiceWithoutOptions',{field: label}), no MetadataClient/tracker id/backtick/API name in the visible message, raw text in a closed details element, 'Show me' reopens the field), AutomationsPillar.authorRefusal-11785.test.tsx (real FlowPreview/FlowInspector: 422 at nodes.2.config.title names 'Title on the step “Notify approver”', raw line under Details, 'Show me' opens node 'tell', unmapped variables.0.name stays under Details). Ablation (implementation committed first, restore points at HEAD): node /home/user/objectstack/scripts/ablation-replace.mjs replaced 'setError(objectSaveRefusal(e, body, locale));' with 'setError(plainRefusal(e));' in StudioDesignSurface.tsx (renders formatMetadataError(e) verbatim again); tool output 'anchor x1 -> x0', blob 0c8c6c6f8f43 -> 4f81f3276532; DataPillar.authorRefusal-11785: 'Tests 2 failed (2)', first failure expected 'Changes not saved: the field “New field” needs at least one option…' received 'The object was not saved: the field
field_2is aselectwith no options…'; restore 'blob == HEAD (0c8c6c6f8f43) and git diff HEAD is empty'. Expected direction (red) observed. No dist build needed: the suite resolves StudioDesignSurface by relative import and @object-ui/data-objectstack by the vitest src alias. Declared narrowing: app-shell full suite (1081 files) not run locally, CI's; the derived set is blind to tests reaching the changed modules only transitively. ESLint on the 9 touched files: 0 errors; StudioDesignSurface.tsx 13 warnings vs 14 on base 16cda0b (none new).","mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 REST writes, each through the fleet relay as one POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create -> POST /repos/objectstack-ai/objectui/pulls (draft forced), relay run 37711540842, read-back 9919 bytes sent = 9919 stored; (2) label-write.mjs --assign os-support-ai -> POST /repos//issues/11848/assignees, relay run 37711617861, read-back MATCHES; (3) this os-dev-report comment -> POST /repos//issues/11785/comments. Plus git pushes of the branch (git transport, not REST): empty-branch probe 16cda0b, then 30600e0, 9efde69, ddd2316, 36165fc.",
"open_questions": [
{
"question": "packages/data-objectstack/README.md is published (files lists README.md) and quotes the guard's old first line in two '// throws:' comments ('MetadataClient.save refused this object metadata write: the field …'). This PR makes both quotes false, but the README is not on the claim's File surface, so it was not edited. How should it land?",
"options": [
"A: the seat amends the claim to add packages/data-objectstack/README.md and sends a patch round on #11848 that changes the two comment prefixes to 'The object was not saved:' (two lines, no other text)",
"B: land #11848 as is and fix the README in a separate docs-only PR",
"C: revert the guard's message prefix and keep only the tracker-id removal (Studio's guard identification would then need the door label, coupling Studio to 'MetadataClient.save')"
],
"recommendation": "A, because the README ships with the package that changes, and a published doc quoting a message the package no longer throws is exactly the drift this card removes. It is a two-line edit in the same PR, and B leaves a known-false published quote in a release window. C reintroduces the class name the card asks to remove."
}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · translateValidationMessage (metadata-admin/i18n.ts) maps a bare 'Required' / 'is required' to 'A name is required.' whatever the issue path; the new sentence passes the server message through it as ResourceEditPage does and inherits that. Reach not measured at a public door (the installed spec's missing-string message is 'Invalid input: expected string, received undefined', which maps correctly). Noted in PR Acceptance notes, not filed · dedupe words: validation message required name is required mistranslation",
"carrier: objectui#11785 seat (same card direction) · publish failures still reach the author as a toast of formatPublishFailures text with raw issue paths; no strip renders them and the card measured no publish case, so this PR converts the three save strips only. Noted in PR Acceptance notes, not filed · dedupe words: publish failure toast raw path author sentence"
],
"gates": [
{
"command": "pnpm check:control-bytes",
"exit": 0,
"verdict": "✅ check-control-bytes: OK (scanned 7832 tracked text file(s); skipped 85 binary)."
},
{
"command": "pnpm check:test-path-roots",
"exit": 0,
"verdict": "✅ check-test-path-roots: OK (2421 filesystem call(s) in 525 of 4618 test file(s); …)"
},
{
"command": "pnpm check:changeset-claims",
"exit": 0,
"verdict": "✅ No pending changeset names a file this change touches."
},
{
"command": "pnpm check:pending-changeset-literals",
"exit": 0,
"verdict": "✅ No test source names a pending changeset."
},
{
"command": "pnpm check:i18n-keys",
"exit": 0,
"verdict": "Every in-scope call-site key resolves against the en pack (3300 keys), …"
},
{
"command": "pnpm check:i18n-drift",
"exit": 0,
"verdict": "No designer-table en value changed in this range."
},
{
"command": "pnpm check:i18n-dead-keys",
"exit": 0,
"verdict": "report-only: 343 candidate(s) …; no engine.studio.refusal.* key listed"
},
{
"command": "pnpm check:i18n-designer-parity",
"exit": 0,
"verdict": "Every en row has a zh row, and every shared row carries the same placeholders."
},
{
"command": "pnpm check:metadata-write-doors",
"exit": 0,
"verdict": "OK 17 metadata write door(s) derived (3 raw PUT, 14 SDK), 3 can carry an object document, 3 reach assertObjectMetadataWritable, …"
},
{
"command": "pnpm check:esm-specifiers",
"exit": 0,
"verdict": "Specifier leg: no un-ledgered package emits an extensionless relative specifier."
},
{
"command": "pnpm check:phantom-deps",
"exit": 0,
"verdict": "✅ Every in-scope import is declared by the package that publishes it."
},
{
"command": "pnpm check:vi-mock-inherit",
"exit": 0,
"verdict": "✅ check-vi-mock-inherit: OK (…)"
},
{
"command": "pnpm check:vi-mock-override-shape",
"exit": 0,
"verdict": "✅ check-vi-mock-override-shape: OK (…)"
},
{
"command": "pnpm check:spec-symbols",
"exit": 0,
"verdict": "✅ ledger anchors: 2 declared; … (red once earlier on a module-local
Docalias in metadataError.ts, renamed SentBody in ddd2316)"},
{
"command": "pnpm check:new-line-citations",
"exit": 0,
"verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0"
},
{
"command": "pnpm check:designer-field-key-parity",
"exit": 0,
"verdict": "designer-field-key-parity: OK"
},
{
"command": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"verdict": "✅ 9 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/11785-author-refusal-text.md."
},
{
"command": "pnpm check:eager-closure",
"exit": 2,
"verdict": "NOT MEASURED: PREREQUISITE NOT MET (needs apps/console/dist from a console build). Stand-in: static-import crawl of app-shell index.ts on base 16cda0b finds flow-node-config.ts, navItemLabel.ts and i18n.ts already IN the barrel closure (control: console/home/QuickActions.tsx OUT, confirmed by hand), so no module is added"
},
{
"command": "pnpm check:doc-examples",
"exit": 2,
"verdict": "NOT MEASURED: needs the scoped doc build first"
},
{
"command": "pnpm check:doc-snippets",
"exit": 2,
"verdict": "NOT MEASURED: needs the scoped doc build first"
},
{
"command": "pnpm check:doc-types",
"exit": 0,
"verdict": "✅ Every documented component type is registered."
},
{
"command": "pnpm exec eslint (9 touched files)",
"exit": 0,
"verdict": "✖ 13 problems (0 errors, 13 warnings); base 16cda0b had 14 on StudioDesignSurface.tsx"
}
],
"deviations": [
"packages/data-objectstack/README.md left stale: off the claim's File surface (stop on breach), reported as open_questions[0] and as a merge prerequisite in the PR body.",
"Claim's line pointers for StudioDesignSurface ':481–:487', ':697–:702', ':785' are package-list READ failures (fetchPackages toasts), not save strips; they are left as they were. The save strips converted are the Data, Automations and Interfaces (leaf + nav) pillars'.",
"ResourceEditPage.tsx not restructured: it already maps a 422's issues to labelled inline errors; for the guard's plain Error it shows err.message, which the guard text change already cleans.",
"packages/data-objectstack/src/metadata-client.objectWriteGuard.test.ts edited (beside the guard, read as 'the tests beside them'): its pin '^MetadataClient\.save refused' inverted to 'the door refuses in the guard's own words, naming no code', which pins the premise Studio's identification rests on.",
"Guard parameter renamed writer -> _writer (name only; the root tsconfig has noUnusedParameters). No type, arity or export change.",
"Container restart mid-run: commit 30600e0 had not been pushed; it survived locally and was pushed on resume, then main 1e1f09e and later 455c646 (objectui#11783's flow-node-config.ts and i18n.ts) were merged; flow-node-config's change (one placeholder removed) does not affect the locator.",
"Two lock acquisitions ended in queue-timeout (exit 99, NOT MEASURED) behind another agent's full packages/app-shell/ vitest run (pid 14586, observed alive at 283% CPU); retried with the same OS_VERIFY_LOCK_SLOT and acquired.",
"label-write was invoked with an OS_FLEET_SESSION=… environment prefix (it has no --session flag); pr_create used dispatch.mjs --session."
],
"files_changed": [
".changeset/11785-author-refusal-text.md",
"packages/app-shell/src/views/metadata-admin/i18n.ts",
"packages/app-shell/src/views/studio-design/AutomationsPillar.authorRefusal-11785.test.tsx",
"packages/app-shell/src/views/studio-design/DataPillar.authorRefusal-11785.test.tsx",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
"packages/app-shell/src/views/studio-design/metadataError.authorRefusal-11785.test.ts",
"packages/app-shell/src/views/studio-design/metadataError.ts",
"packages/data-objectstack/src/metadata-client.objectWriteGuard.test.ts",
"packages/data-objectstack/src/object-metadata-write-guard.test.ts",
"packages/data-objectstack/src/object-metadata-write-guard.ts"
],
"line_budget": "not applicable (no skills/ surface)"
}
objectstack-fleet commentedon Oct 8, 2026
Claim amendment —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T01:14Z. It amends claim6049060030after the dev's report6050124322. The claim stands otherwise.packages/data-objectstack/README.md, only its two// throws:comments that quote the write guard's old first line ("MetadataClient.save refused this object metadata write: …").@object-ui/data-objectstackpublishes its README (fileslists it). PR objectui#11848 changes the guard's message, so both quotes become false in the published package. A published text that this change makes false is this change's to fix, in the same PR. The dev's open question is answered A: change the two quoted prefixes to the guard's new wording, with no other README text.StudioDesignSurface.tsxpointers:481–:487,:697–:702and:785are package-list read failures (fetchPackagestoasts), not save strips. The dev converted the save strips of the Data, Automations and Interfaces pillars and left those toasts alone, which is right.Clause-②: nostands: the guard's signature, error type and exports are unchanged. Its parameter is renamedwriter→_writer, a name only.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{
"issue": 11785,
"status": "done",
"addendum_to": "6050124322",
"branch": "claude/issue-11785-author-refusal-text",
"pr": "#11848",
"head": "00304bc",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8",
"premise_still_valid": true,
"summary": "Patch round per claim amendment 6050143821 (answer A). packages/data-objectstack/README.md: the two '// throws:' comment lines (old main :784 and :811) changed from 'MetadataClient.save refused this object metadata write: the field' to 'The object was not saved: the field', which is the guard's first line as measured by running assertObjectMetadataWritable on the README's two example bodies (account/owner lookup, deal/stage select with options []). The second line of each quote already matched and is unchanged. No other README text changed (git diff: 2 insertions, 2 deletions). main is still 455c646 (already merged), so no merge was needed. The PR body is updated: the prerequisite is marked done and the patch-round gates name 00304bc.",
"gates": [
{
"command": "turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2 (locked)",
"exit": 0,
"verdict": "BUILD_EXIT=0"
},
{
"command": "pnpm --filter @object-ui/data-objectstack type-check (locked)",
"exit": 0,
"verdict": "tsc --noEmit, no output"
},
{
"command": "pnpm check:doc-snippets (locked; corpus: every README.md under packages/)",
"exit": 0,
"verdict": "Every covered documentation snippet compiles against the built types."
},
{
"command": "pnpm check:readme-exports",
"exit": 0,
"verdict": "✅ check-readme-exports: OK (43 tracked README(s) under packages/ …); an earlier pre-build run was a PREREQUISITE failure (no dist), not a finding"
},
{
"command": "pnpm check:changeset-claims",
"exit": 0,
"verdict": "✅ No pending changeset names a file this change touches."
},
{
"command": "pnpm check:pending-changeset-literals",
"exit": 0,
"verdict": "✅ No test source names a pending changeset."
},
{
"command": "pnpm check:doc-types",
"exit": 0,
"verdict": "✅ Every documented component type is registered."
},
{
"command": "pnpm check:doc-fences",
"exit": 0,
"verdict": "✅ check:doc-fences — every TypeScript block in 227 document(s) is fenced ts/tsx/typescript, …"
},
{
"command": "pnpm check:control-bytes",
"exit": 0,
"verdict": "✅ check-control-bytes: OK (scanned 7832 tracked text file(s); skipped 85 binary)."
},
{
"command": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"verdict": "✅ 9 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/11785-author-refusal-text.md."
}
],
"mcp_calls": "0",
"api_writes": "2 relay writes (one POST /repos/objectstack-ai/objectstack/dispatches each): issue_patch PATCH /repos//issues/11848 body (run 37712797115, read-back 11099 = 11099 identical; footer sent in the bare form, the session URL kept in body prose); this comment POST /repos//issues/11785/comments. Plus one git push 36165fc..00304bc.",
"files_changed": [
"packages/data-objectstack/README.md"
],
"deviations": [
"The worktree was recreated at /home/user/objectui-issue-11785 on the branch for this round and removed after it."
]
}
objectstack-fleet commentedon Oct 8, 2026
ACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T01:33Z. PR objectui#11848, head00304bc.PR shape: draft against
main, with455c646merged in (no rebase).mainhas since moved one commit (59ce048, seat 1's objectui#11790), andgit merge-treeoforigin/mainand this head is clean; the queue tests that merge. First lineFixes #11785, no other closing keyword.Clause-②: noat line start. Commits carry only the model-free trailer pair. Assigned toos-support-ai.Scope: 11 files, +1142/−79, on the claim's surface as amended (
6050143821):studio-design/StudioDesignSurface.tsx: the Data, Automations and Interfaces pillars' save strips (thefetchPackagestoasts are left alone, as the amendment corrected);studio-design/metadataError.ts: the refusal view model (StudioRefusal, the three per-pillar locators,plainRefusalas the unchanged fallback);metadata-admin/i18n.ts;data-objectstack'sobject-metadata-write-guard.ts(message text only) and the two// throws:quotes in its publishedREADME.md;patchon both packages).The published
formatMetadataErroris untouched, so its other call sites print what they printed. Nothing is added to either package entry. No governed path.Diff read (the seat's own):
@objectstack/specand the tracker ids, and now begin "The object was not saved: the field …". The field, its type and the remedy are kept. The signature is unchanged;writeris renamed_writer, a name only.eas that refusal only whenehas no status, no issues, and a byte-identical message. Anything else falls back toplainRefusal, which is the old verbatim text.formatMetadataError(e).README patch round (
36165fc..00304bc): exactly two lines,packages/data-objectstack/README.mdat:784and:811, each// throws:prefix now the guard's measured first line. Read by the seat on the compare. After this PR, the old prefix "refused this object metadata write" has no occurrence in the tree outside changelogs (onmain: 2 in the guard, 2 in the README).Ruling honoured: triage's direction on the card: an author sentence, a located field, the technical detail collapsible. The amendment's answer A (README quotes fixed in this PR) is done.
Changeset sentences checked against the head:
assertObjectMetadataWritableno longer prints the door's class name, a package name or tracker ids … Its signature, error type and exports are unchanged";formatMetadataErroris unchanged … Nothing is added to either package entry".Reverse verification (dev report):
ablation-replace.mjs: the Data page's catch put back toplainRefusal(e)gives both Data pins red (2/2), the first receiving the guard's old-style text. Restored with the blob equal to HEAD.36165fc: 228 files, 2608 tests passed. It includes the 11 plugin-designerMetadataFieldsPage*suites, which are the non-StudioformatMetadataErrorcallers and the control.00304bc:check:doc-snippets(every package README) andcheck:readme-exportsexit 0 after the build; the type-check exit 0.Gates: CI on
00304bc(head_shaequals the PR head): 43 runs, 40 success, 3 skipped (Test (coverage), its shard template,dependabot), 0 failure.LintandType Checkare success. Mergeable stateclean.Contract review: not required (
Clause-②: no).Findings:
translateValidationMessagemaps a bareRequiredto "A name is required." whatever the path, and the new sentence inherits it asResourceEditPagedoes. Not reached at a public door in this run, so it does not pass the filing gate →Acceptance notesformatPublishFailures), and create dialogs printerror.message. Both are surfaces the card did not measure →Acceptance notesFollow-up: objectui#11786 (the autosave refusing intermediate states) is serial behind this card and is picked once this lands.
Landing: ready + auto-merge through the queue, now.
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Landed —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T01:53Z. PR objectui#11848 merged through the queue as4a9fe31at 2026-10-08T01:51Z.59ce048, an ancestor oforigin/main.git merge-treeof that parent and the accepted head00304bc(tree77c9270con both).59ce048→4a9fe31, underpackages/:StudioRefusalStrip: 0 → 5.packages/data-objectstack/src/metadata-error.ts(formatMetadataError) is byte-identical on both sides, so its other call sites print what they printed.Fixes #11785. It is the only issue closed since 01:30Z.pm:dispatchedis removed.6049737578, is now met.Generated by Claude Code
fix(app-shell): Studio refusals read as an author sentence, with the …