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
spec(view): FormViewSchema drawerSide / drawerWidth are accepted on a form view and read by no form-view surface; the describe says the question "stays open on #27153", which is closed #29012
Filing gate: ① a product defect, a QA run clause fail (studio-authoring.no-entry-property-matrix acceptance[2]: a key stored, served and silently inert).
Business reason: an author who writes drawerSide: 'left', drawerWidth: '480px' on a form view gets a valid save and publish (a bad enum is even refused 422), and the form still opens as the centred dialog or the page. ADR-0049 says such a key is either enforced or removed. The describe in packages/spec/src/ui/view.zod.ts (about L5155) says the drawer half of that question "stays open on #27153", but #27153 closed on 2026-10-28 after retiring only buttons.reset, so no open card owns it.
Reader who acts: the triage seat, then the domain:spec lane: retire both keys on a form view (tombstone and conversion) or open the ui half to render a form view in a drawer. QA suggestion only: p3.
Duplicate search: drawerSide → 9 hits, all closed: #27153 (retired buttons.reset, left the drawer keys), #26843, #27155 (retired type: 'drawer'), #27159 (ObjectForm drops the drawer branch). drawerWidth → 15 hits, none open on this.
Batch-of: release-18.3.0-w4-c3b1 — 16 cards from QA run #29002 (subject 7fa9873f; the implementer re-checks the landing site on current main).
Reproduction
On a writable package: PUT /api/v1/meta/view/qar8_fdr.form?mode=draft&package=PKG with {object:'qar8_fdr', viewKind:'form', isDefault:true, config:{type:'simple', sections:[…], drawerSide:'left', drawerWidth:'480px'}}, then publish. The live read carries both keys.
Open the list → New, and /_console/forms/qar8_fdr.form.
Expected: a 480 px drawer from the left, or a refusal at save. Actual: the same centred dialog / in-page form as a control view without the keys; drawerSide:'middle' → 422, so the key is validated and never read. Reproduced 2 times.
Mechanism
Only ui/packages/plugin-form/src/DrawerForm.tsx reads them, for a React ObjectForm block given formType='drawer'; no metadata form-view surface reaches it (the describe says so: "Inert on a form view since type: 'drawer' was retired").
Claim: PM loop round 1 · 2026-11-02T09:28Z
Session: session_01ADHkmPi25XXKx92Xmg4viS (seat); dev = card thread session_01ADHkmSVA1CYQ5wh8VMGZ5r
Account: os-steve
Branch: claude/project-thread-6xhq0v
Worktree: the card thread's own checkout of objectstack-ai/objectstack
Domain: domain:spec
Seat: domain:spec#1
File surface: packages/spec/src/ui/view.zod.ts (FormViewSchema.drawerSide / drawerWidth and their describes only, ≈L5155–5165) and the retirement surfaces the spec-property-retirement skill names (tombstone, stored-row conversion, ADR-0087 entry, generated baselines, forms and pins); ui/packages/plugin-form/** only if the removal reds Type Check UI (AGENTS.md checklist 4); regenerated content/docs/references/**; root .changeset/; not the hideFields lines PR #29083 moves, not the personal scope/sharing keys (#29037) (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); one CONTRACT_REVIEW_TIER review (key retirement) before landing, effort: xhigh
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Responsibility: packages/spec view.zod.ts FormViewSchema drawerSide/drawerWidth | #27155 retired type: 'drawer' and #27159 dropped ObjectForm's drawer branch; #27153 closed retiring only buttons.reset and left these keys | authors who save the keys on a form view and get a valid, inert save
Thread-read: 6571544001
Premise: holds (on origin/main dedc350519 L5163 / L5165 declare both keys; the describe defers to closed #27153)
Serial constraints cleared: PR #29083 (#28912, same file) is in the merge queue; the implementer merges main after it lands and before pushing. #29037 (same file) waits for this card.
Ruling-ref: triage 6571544001 — retire route under ADR-0049; the direction follows from #27155 and #27159.
{
"issue": 29012,
"status": "done",
"branch": "claude/project-thread-6xhq0v",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29287",
"head": "8c7bfc303c46d669e401ac727afde0e3e832d35e",
"session": "session_01ADHkmSVA1CYQ5wh8VMGZ5r",
"premise_still_valid": true,
"summary": "FormViewSchema.drawerSide / drawerWidth are retiredKey() tombstones refused at every form-view door and defineStack with a prescription; the React ObjectForm block keeps both as overlay binding props (dataProps no longer reads them from FormViewSchema; REACT_OVERLAY_SHADOWS.ObjectForm ledgers the tombstone-name collision), and the object-form page block keeps them in ObjectFormPropsSchema. ADR-0087 kit: D2 form-view-drawer-keys-removed (retiredFromLoadPath, retiredAfter 18.2.0, form payloads + viewItems, never page components), D3 ui-form-view-drawer-keys-retired, two RETIRED_KEYS_BY_MAJOR[18] entries, step-18 rationale fragment (order 116), removal-version pin rows, liveness rows dead (view 75/8 -> 73/10), regenerated authorable-surface/docs/react-blocks.md/state-counts, BREAKING minor changeset. Mechanism assumptions measured at 104cd1a5: no metadata form-view surface reads either key (only ObjectFormContainer -> DrawerForm, behind the block's formType='drawer'); drawerWidth had no size-bucket conversion; authored uses on form views 0 in examples/ and skills/ (control: submitBehavior 8 in examples/); the ui prop types are the block's own (DrawerFormSchema, ObjectFormSchema), so no ui/ edit. PR is NOT governed: react-blocks.md lifts as a pure regeneration (check-governed-merges --test: 0 of 20 paths).",
"tests": "At 0dc8fcc3 (tree = head minus the changeset file), all under os-verify-lock VERDICT command-exit 0: spec typecheck exit 0; spec test (local) Test Files 789 passed 1 skipped (790), Tests 23371 passed; spec test:repo Test Files 88 passed (88), Tests 1477 passed; @objectstack/lint test Test Files 189 passed (189), Tests 7825 passed 5 skipped. At 8c7bfc30: ui @object-ui/plugin-form test (from ui/) Test Files 217 passed (217), Tests 2407 passed 1 skipped (first run 3 files failed on prerequisite: @objectstack/client unbuilt); ui type-check NOT MEASURED locally (prerequisite: ui workspace packages unbuilt, TS2307) — Type Check UI in CI is the reading; by source no ui type derives the keys from FormView. Ablations via ablation-replace.mjs, restored blob == HEAD: tombstone -> old z.enum: new pin 7 failed / 22 passed (29); conversion stripKeys -> pass-through: 3 failed / 235 passed (238). New pin src/ui/form-view-drawer-keys-retirement.test.ts 29/29.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 8c7bfc30: 112 derived, 112 run; --ran: '112 derived famil(ies) accounted for — 112 run, 0 NOT-MEASURED (a DERIVED zero)'. Six first-pass prerequisite exits (check-plugin-teardown-shape --self-test exit 3: pinned commit fetched; lint check:doc-formula-expressions / check:doc-security-posture exit 3, spec check:skill-examples exit 3, check:dts-closure exit 1, check:dual-build-cjs-loads exit 3: packages unbuilt) all exit 0 after turbo build --filter='./packages/**' 78/78. check-adr-0087-registration --base origin/main exit 0 (registered, both ids new); check-changeset-no-major --event on the PR body exit 0 (LEVEL AXIS no (narrowing) + narrowed, minor); check-empty-changeset exit 0; check-governed-merges --test: NOT governed. CI families: in_progress on the PR's check-runs at report time.",
"dogfood_battery": "8c7bfc30 · os-verify-lock VERDICT command-exit 0 (held 26m51s) · Test Files 388/391 (388 passed, 3 skipped) · Tests 3208/3236 (3208 passed, 28 skipped) · no failures",
"mcp_calls": "0 — no MCP GitHub calls (reads went through gh api REST GETs)",
"api_writes": "2 — relay pr_create (repository_dispatch fw-20261102T110015Z-622d56 -> POST /repos/objectstack-ai/objectstack/pulls, #29287); this os-dev-report comment (post-stamped -> POST /repos/objectstack-ai/objectstack/issues/29012/comments)",
"files_changed": [
".changeset/29012-form-view-drawer-keys-retired.md",
"content/docs/references/api/protocol.mdx (generated)",
"content/docs/references/ui/view.mdx (generated)",
"packages/spec/authorable-surface/ui.json (generated)",
"packages/spec/liveness/state-counts/view.md (generated)",
"packages/spec/liveness/view.json",
"packages/spec/src/conversions/registry.ts",
"packages/spec/src/migrations/entries/retired-keys/18.ui__FormView__drawerSide.ts",
"packages/spec/src/migrations/entries/retired-keys/18.ui__FormView__drawerWidth.ts",
"packages/spec/src/migrations/entries/semantic/18.ui-form-view-drawer-keys-retired.ts",
"packages/spec/src/migrations/registry.ts.template",
"packages/spec/src/shared/retired-key-removal-version.pin.test.ts",
"packages/spec/src/system/metadata-form-zod-reconciliation.test.ts",
"packages/spec/src/ui/form-view-drawer-keys-retirement.test.ts (new)",
"packages/spec/src/ui/form-view-type-layout-retirement.test.ts",
"packages/spec/src/ui/react-blocks.ts",
"packages/spec/src/ui/view-metadata-schema.test.ts",
"packages/spec/src/ui/view.zod.ts",
"packages/spec/vitest.repo-tests.json",
"skills/objectstack-ui/references/react-blocks.md (generated, pure-regeneration lift)"
],
"line_budget": "20 files, +707 / -64 = 771 changed lines (generated included), under the 3000 human-merge threshold; not governed",
"deviations": [
"File surface: the claim lists view.zod.ts plus the skill's retirement surfaces; this diff also edits packages/spec/src/ui/react-blocks.ts (the block's dataProps read FormViewSchema, so keeping the block's drawer props needed the overlay move + REACT_OVERLAY_SHADOWS row) and regenerates skills/objectstack-ui/references/react-blocks.md. Both are consequences of the tombstone, not scope growth.",
"Forced edit to another entry's fixture: form-view-presentation-types-removed's quick bystander drawerSide -> title (whole-table fixture disjointness), plus its docblock sentence.",
"PR opened at 0dc8fcc3 because the changeset commit 8c7bfc30 was still local; pushed about a minute later. The PR body already names 8c7bfc30, which is the head now; CI on 0dc8fcc3 is superseded.",
"Session-context asked to set the PR assignee/reviewer via MCP; not done (standard order forbids MCP writes, os-dev forbids PR assignees).",
"First conversion ablation used a throwing replacement and reddened every form-view fixture; discarded and rerun as a pass-through (the reading above)."
],
"open_questions": [
{
"question": "The pending .changeset/27155-form-view-type-layout-only.md 'Unchanged' bullet says drawerSide / drawerWidth (and splitDirection) stay declared; at 18.3.0 that is false for all three. Correct it?",
"options": [
"A Leave it: #27159 left the splitDirection half the same way; both entries ship in one release and the release notes are compiled centrally (Check Changeset stays green)",
"B Seat or a follow-up commit edits the bullet (DELIBERATE CORRECTION class: check-empty-changeset reds by design, not a required context)"
],
"recommendation": "A, because it matches the #27159 precedent in the same bullet and keeps every changeset gate green; the release compiler reconciles same-release entries"
}
],
"out_of_scope_findings": [
"class: none (comment drift) · reach: n/a · ui/packages/types/src/objectql.ts ObjectFormSchema key-taxonomy docblock lists drawerSide/drawerWidth as [spec-aligned] FormView keys; now block-own on both sides · carrier: none — noted in Acceptance notes, not filed",
"class: none (QA prose) · reach: n/a · docs/qa/platform-checklist/areas/studio-authoring.json rows scoring the drawer keys 'fail today' now meet a save refusal · carrier: QA lane re-score — noted, not filed"
]
}
pm:dispatched is removed. Seat ACCEPT, a round-1 FAIL and a round-2 CONTRACT_REVIEW_TIER PASS (6577589273) on head ffc3fe89. FormViewSchema.drawerSide / drawerWidth are retired tombstones (BREAKING, D2 conversion form-view-drawer-keys-removed); the React ObjectForm block keeps both as its own overlay props. The pending 27155 note was corrected in the same release (deliberate-correction class; the Check Changeset red was by design). The ui/types docblock drift is carried by #29284. Next on view.zod.ts: #29037, then #28522.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: studio-authoring.no-entry-property-matrix
Triage:
domain:spec· p2 ·pm:queue· 2026-11-02T07:26Z⛔ Not a claim.
ObjectFormdrops thesplit/drawer/modalbranches andSplitFormretires; showcasetaskviews re-spelled (ADR-0050 cutover, renderer half of #27155) #27159; domain:spec, retire route under ADR-0049. A key that saves and does nothing is a user-visible defect, p2 (QA suggested p3). The retire direction already follows from spec(view): narrowFormView.typeto layout only (simple | tabbed | wizard) — retiresplit,drawer,modalwith tombstones (ADR-0050 Accepted, #27032 letter A′) #27155 and ui(plugin-form):ObjectFormdrops thesplit/drawer/modalbranches andSplitFormretires; showcasetaskviews re-spelled (ADR-0050 cutover, renderer half of #27155) #27159, so pm:queue; the item is P2, so the release rule does not apply.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS
Claim: PM loop round 1 · 2026-11-02T09:28Z
Session:
session_01ADHkmPi25XXKx92Xmg4viS(seat); dev = card threadsession_01ADHkmSVA1CYQ5wh8VMGZ5rAccount:
os-steveBranch:
claude/project-thread-6xhq0vWorktree: the card thread's own checkout of
objectstack-ai/objectstackDomain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/src/ui/view.zod.ts(FormViewSchema.drawerSide/drawerWidthand their describes only, ≈L5155–5165) and the retirement surfaces thespec-property-retirementskill names (tombstone, stored-row conversion, ADR-0087 entry, generated baselines, forms and pins);ui/packages/plugin-form/**only if the removal reds Type Check UI (AGENTS.md checklist 4); regeneratedcontent/docs/references/**; root.changeset/; not thehideFieldslines PR #29083 moves, not the personal scope/sharing keys (#29037) (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default — the tier is the PM's per-card call (floor sonnet · default opus · ceiling fable); one CONTRACT_REVIEW_TIER review (key retirement) before landing,effort: xhighClause-②: no (narrowing)
Metadata-protocol: narrowed
Responsibility:
packages/spec view.zod.ts FormViewSchema drawerSide/drawerWidth | #27155 retired type: 'drawer' and #27159 dropped ObjectForm's drawer branch; #27153 closed retiring only buttons.reset and left these keys | authors who save the keys on a form view and get a valid, inert saveThread-read: 6571544001
Premise: holds (on origin/main
dedc350519L5163 / L5165 declare both keys; the describe defers to closed #27153)Serial constraints cleared: PR #29083 (#28912, same file) is in the merge queue; the implementer merges main after it lands and before pushing. #29037 (same file) waits for this card.
Ruling-ref: triage 6571544001 — retire route under ADR-0049; the direction follows from #27155 and #27159.
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmSVA1CYQ5wh8VMGZ5r
os-dev-report
{ "issue": 29012, "status": "done", "branch": "claude/project-thread-6xhq0v", "pr": "https://github.com/objectstack-ai/objectstack/pull/29287", "head": "8c7bfc303c46d669e401ac727afde0e3e832d35e", "session": "session_01ADHkmSVA1CYQ5wh8VMGZ5r", "premise_still_valid": true, "summary": "FormViewSchema.drawerSide / drawerWidth are retiredKey() tombstones refused at every form-view door and defineStack with a prescription; the React ObjectForm block keeps both as overlay binding props (dataProps no longer reads them from FormViewSchema; REACT_OVERLAY_SHADOWS.ObjectForm ledgers the tombstone-name collision), and the object-form page block keeps them in ObjectFormPropsSchema. ADR-0087 kit: D2 form-view-drawer-keys-removed (retiredFromLoadPath, retiredAfter 18.2.0, form payloads + viewItems, never page components), D3 ui-form-view-drawer-keys-retired, two RETIRED_KEYS_BY_MAJOR[18] entries, step-18 rationale fragment (order 116), removal-version pin rows, liveness rows dead (view 75/8 -> 73/10), regenerated authorable-surface/docs/react-blocks.md/state-counts, BREAKING minor changeset. Mechanism assumptions measured at 104cd1a5: no metadata form-view surface reads either key (only ObjectFormContainer -> DrawerForm, behind the block's formType='drawer'); drawerWidth had no size-bucket conversion; authored uses on form views 0 in examples/ and skills/ (control: submitBehavior 8 in examples/); the ui prop types are the block's own (DrawerFormSchema, ObjectFormSchema), so no ui/ edit. PR is NOT governed: react-blocks.md lifts as a pure regeneration (check-governed-merges --test: 0 of 20 paths).", "tests": "At 0dc8fcc3 (tree = head minus the changeset file), all under os-verify-lock VERDICT command-exit 0: spec typecheck exit 0; spec test (local) Test Files 789 passed 1 skipped (790), Tests 23371 passed; spec test:repo Test Files 88 passed (88), Tests 1477 passed; @objectstack/lint test Test Files 189 passed (189), Tests 7825 passed 5 skipped. At 8c7bfc30: ui @object-ui/plugin-form test (from ui/) Test Files 217 passed (217), Tests 2407 passed 1 skipped (first run 3 files failed on prerequisite: @objectstack/client unbuilt); ui type-check NOT MEASURED locally (prerequisite: ui workspace packages unbuilt, TS2307) — Type Check UI in CI is the reading; by source no ui type derives the keys from FormView. Ablations via ablation-replace.mjs, restored blob == HEAD: tombstone -> old z.enum: new pin 7 failed / 22 passed (29); conversion stripKeys -> pass-through: 3 failed / 235 passed (238). New pin src/ui/form-view-drawer-keys-retirement.test.ts 29/29.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 8c7bfc30: 112 derived, 112 run; --ran: '112 derived famil(ies) accounted for — 112 run, 0 NOT-MEASURED (a DERIVED zero)'. Six first-pass prerequisite exits (check-plugin-teardown-shape --self-test exit 3: pinned commit fetched; lint check:doc-formula-expressions / check:doc-security-posture exit 3, spec check:skill-examples exit 3, check:dts-closure exit 1, check:dual-build-cjs-loads exit 3: packages unbuilt) all exit 0 after turbo build --filter='./packages/**' 78/78. check-adr-0087-registration --base origin/main exit 0 (registered, both ids new); check-changeset-no-major --event on the PR body exit 0 (LEVEL AXIS no (narrowing) + narrowed, minor); check-empty-changeset exit 0; check-governed-merges --test: NOT governed. CI families: in_progress on the PR's check-runs at report time.", "dogfood_battery": "8c7bfc30 · os-verify-lock VERDICT command-exit 0 (held 26m51s) · Test Files 388/391 (388 passed, 3 skipped) · Tests 3208/3236 (3208 passed, 28 skipped) · no failures", "mcp_calls": "0 — no MCP GitHub calls (reads went through gh api REST GETs)", "api_writes": "2 — relay pr_create (repository_dispatch fw-20261102T110015Z-622d56 -> POST /repos/objectstack-ai/objectstack/pulls, #29287); this os-dev-report comment (post-stamped -> POST /repos/objectstack-ai/objectstack/issues/29012/comments)", "files_changed": [ ".changeset/29012-form-view-drawer-keys-retired.md", "content/docs/references/api/protocol.mdx (generated)", "content/docs/references/ui/view.mdx (generated)", "packages/spec/authorable-surface/ui.json (generated)", "packages/spec/liveness/state-counts/view.md (generated)", "packages/spec/liveness/view.json", "packages/spec/src/conversions/registry.ts", "packages/spec/src/migrations/entries/retired-keys/18.ui__FormView__drawerSide.ts", "packages/spec/src/migrations/entries/retired-keys/18.ui__FormView__drawerWidth.ts", "packages/spec/src/migrations/entries/semantic/18.ui-form-view-drawer-keys-retired.ts", "packages/spec/src/migrations/registry.ts.template", "packages/spec/src/shared/retired-key-removal-version.pin.test.ts", "packages/spec/src/system/metadata-form-zod-reconciliation.test.ts", "packages/spec/src/ui/form-view-drawer-keys-retirement.test.ts (new)", "packages/spec/src/ui/form-view-type-layout-retirement.test.ts", "packages/spec/src/ui/react-blocks.ts", "packages/spec/src/ui/view-metadata-schema.test.ts", "packages/spec/src/ui/view.zod.ts", "packages/spec/vitest.repo-tests.json", "skills/objectstack-ui/references/react-blocks.md (generated, pure-regeneration lift)" ], "line_budget": "20 files, +707 / -64 = 771 changed lines (generated included), under the 3000 human-merge threshold; not governed", "deviations": [ "File surface: the claim lists view.zod.ts plus the skill's retirement surfaces; this diff also edits packages/spec/src/ui/react-blocks.ts (the block's dataProps read FormViewSchema, so keeping the block's drawer props needed the overlay move + REACT_OVERLAY_SHADOWS row) and regenerates skills/objectstack-ui/references/react-blocks.md. Both are consequences of the tombstone, not scope growth.", "Forced edit to another entry's fixture: form-view-presentation-types-removed's quick bystander drawerSide -> title (whole-table fixture disjointness), plus its docblock sentence.", "PR opened at 0dc8fcc3 because the changeset commit 8c7bfc30 was still local; pushed about a minute later. The PR body already names 8c7bfc30, which is the head now; CI on 0dc8fcc3 is superseded.", "Session-context asked to set the PR assignee/reviewer via MCP; not done (standard order forbids MCP writes, os-dev forbids PR assignees).", "First conversion ablation used a throwing replacement and reddened every form-view fixture; discarded and rerun as a pass-through (the reading above)." ], "open_questions": [ { "question": "The pending .changeset/27155-form-view-type-layout-only.md 'Unchanged' bullet says drawerSide / drawerWidth (and splitDirection) stay declared; at 18.3.0 that is false for all three. Correct it?", "options": [ "A Leave it: #27159 left the splitDirection half the same way; both entries ship in one release and the release notes are compiled centrally (Check Changeset stays green)", "B Seat or a follow-up commit edits the bullet (DELIBERATE CORRECTION class: check-empty-changeset reds by design, not a required context)" ], "recommendation": "A, because it matches the #27159 precedent in the same bullet and keeps every changeset gate green; the release compiler reconciles same-release entries" } ], "out_of_scope_findings": [ "class: none (comment drift) · reach: n/a · ui/packages/types/src/objectql.ts ObjectFormSchema key-taxonomy docblock lists drawerSide/drawerWidth as [spec-aligned] FormView keys; now block-own on both sides · carrier: none — noted in Acceptance notes, not filed", "class: none (QA prose) · reach: n/a · docs/qa/platform-checklist/areas/studio-authoring.json rows scoring the drawer keys 'fail today' now meet a save refusal · carrier: QA lane re-score — noted, not filed" ] }Stamped 2026-11-02T11:03Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#1 · os-steve · session_01ADHkmPi25XXKx92Xmg4viS
Landed · 2026-11-02T13:54Z
b5e7ba5552, through the merge queuecompletedbyFixes #29012pm:dispatchedis removed. Seat ACCEPT, a round-1 FAIL and a round-2 CONTRACT_REVIEW_TIER PASS (6577589273) on headffc3fe89.FormViewSchema.drawerSide/drawerWidthare retired tombstones (BREAKING, D2 conversionform-view-drawer-keys-removed); the ReactObjectFormblock keeps both as its own overlay props. The pending 27155 note was corrected in the same release (deliberate-correction class; the Check Changeset red was by design). The ui/types docblock drift is carried by #29284. Next onview.zod.ts: #29037, then #28522.