Skip to content

spec(view): narrow FormView.type to layout only (simple | tabbed | wizard) — retire split, drawer, modal with tombstones (ADR-0050 Accepted, #27032 letter A′) #27155

Closed

Description

@objectstack-fleet

Filing gate ③ (maintainer-directed). Ruling 6464210455 on #27032 (batch #421 item 3, letter A′, maintainer 「其他同意」 2026-10-28): ADR-0050 Accepted, the cutover lands now as a (narrowing) minor. Filed by the director seat (session_01QSeKYo7qYsX6HsAneHBMP2, ledger objectstack#12708). ⛔ Not a claim; triage sets the lane (domain:spec expected) and grade.

Ruling-ref: 6464210455

维护者速读

  • 改了什么: FormView.type 只剩布局三值 simple | tabbed | wizard;split、drawer、modal 发布时拒收,拒收信息带迁移处方(split → 列表的 navigation.mode: 'split' + subforms;drawer / modal → 调用方的打开方式)。section.pane 随 split 退役。
  • 为什么改: 一个字段混两维(布局 + 呈现 + 视图模式),「模态框里放 tabbed 表单」已经靠 [P1] Finish ADR-0021 analytics migration (chart view / dashboard+Studio / report) #1890 实现,三个冗余值零业务使用(本树 showcase task 2 处、hotcrm lead 3 处,全是演示视图)。
  • 风险与回滚: BREAKING(narrowing);本仓无 spec-major 窗口,按 AGENTS.md L1084–1090 走 minor + 迁移 + tombstone + ADR-0087 处置(先例 [Decision] A list view's addRecord defaults (enabled true, position bottom, mode inline) are not what the renderer does: enforce the spec, or make the spec say what renders (objectui#13099) #24692 B′)。渲染器半边是子卡,先于本卡合并会让演示视图发布失败 ⇒ 子卡 Blocked-by: 本卡,两者同窗落地。
  • 先看: packages/spec/src/ui/view.zod.ts:4546–4551 与 L4034(pane)、L4619–4627。
  • 两分钟验证: 一个 type: 'modal' 的 form view 在 objectstack build 被拒且信息点名迁移路径。
  • 需要您做的: 无(spec PR 不是受管面;若 PR 顺带改 docs/adr/0050-* 状态行则需您批)。

Measured (on origin/main e6e41998, 2026-10-28)

  • Enum: view.zod.ts:4546–4551 lists six values, default simple.
  • Live usage of the three values (non-test): examples/app-showcase/src/ui/views/task.view.ts:421 (split), :431 (drawer); hotcrm src/sales/views/lead.view.ts:747 (split), :796 (drawer), :839 (modal) at hotcrm 6c52f22 (spec pin 18.2.0). No business metadata.
  • Renderer still executes them: ui/packages/plugin-form/src/ObjectForm.tsx L41–42 imports, L516 / L553 branches; ModalForm.tsx:167, 950 carry the [P1] Finish ADR-0021 analytics migration (chart view / dashboard+Studio / report) #1890 layout forwarding (kept).

Task

  • FormViewSchema.type → z.enum(['simple','tabbed','wizard']); split / drawer / modal refused with retiredKey()-style tombstones carrying the FROM → TO mapping above; section.pane retired with split (tombstone).
  • The spec-property-retirement kit: ADR-0087 disposition in the changeset, liveness ledger, generated baselines / forms / docs, pin tests; stored-metadata survey of the three values (expected: the five demo views only).
  • Re-spell examples/app-showcase task.view.ts L421 / L431 to layouts (tabbed / simple) and demo the open modes via the list's navigation.mode.
  • ADR-0050 status line → "Accepted — cutover card #N (this card)": rides the docs(adr): the 19 stale Proposed records (status date before 2026-07-26) are ruled by the maintainer in four batches of five — carrier for the rulings and the status-line PRs #26553 closeout docs PR (Tier H), or its own XS PR; ⛔ not mixed into this spec PR.
  • hotcrm lead.view.ts L747 / L796 / L839: owed to the hotcrm seat (unreachable from the filing session); named in the PR body as Skills-docs: follow-up owed — hotcrm src/sales/views/lead.view.ts.

Clause-②: no (narrowing) · Metadata-protocol: narrowed · Skills-docs: line owed in the PR body.

Child: the renderer half (domain:ui) is its own card, Blocked-by: this one. Dedupe: #27032 (ruled, closed), #24692 (closed, B′), #1890 (closed, the unlock), objectui#1763 (key drift, out of scope); no open card narrows FormView.type.

Activity

  1. added
    enhancementNew feature or request
    pm:queueReady for the PM dispatch loop
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 28, 2026
  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · 2026-10-28T09:19Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-9k357q (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-27155-<slug>)
    Worktree: objectstack-issue-27155
    Domain: domain:spec
    Seat: domain:spec#3
    Ruling-ref: 6464210455 (on #27032, letter A′: FormView.type narrows to simple | tabbed | wizard; split / drawer / modal refused with tombstones; section.pane retires with split)
    File surface: packages/spec/src/ui/view.zod.ts (FormViewSchema.type, section.pane, and the split / drawer parameter keys splitDirection, splitSize, splitResizable, drawerSide, drawerWidth where no live reader reads them on a surviving type), their tests, the ADR-0087 disposition, the liveness ledger, regenerated baselines / forms / docs / ui manifest, examples/app-showcase/src/ui/views/task.view.ts, one changeset per touched published package. ⛔ Not ui/packages/** renderer branches, not component.zod.ts object-form formType (both the domain:ui child's), not docs/adr/**`` (stop on breach; explain in the report) Container & model: M, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (narrowing; one CONTRACT_REVIEW_TIER review owed, run by the seat; full dogfood owed), effort: highClause-②: no (narrowing) Metadata-protocol: narrowed Responsibility: the spec lane ownsFormViewSchema; the renderer half is the domain:uichild card,Blocked-by:this one Thread-read: 6464210455 Premise: holds onorigin/main 6866e2e: view.zod.ts:4546-4551lists sixtypevalues;split/drawer/modalappear only in demo views (showcasetask.view.ts, hotcrm lead.view.ts) Serial constraints cleared: no open PR on FormViewSchema (open PRs searched 09:13Z)Seat rulings on the dev's three measured questions: (1)navigation.mode: 'split'was retired by objectstack-ai/objectstack#26804 (17b5152d), so the tombstones prescribe live values only:split→tabbed/simple, master-detail through subforms, the side-by-side pane being the reader's own preference; drawer/modal→ the caller's open mode. The PR body names this as the ruling's intent applied to the current tree, citing objectstack-ai/objectstack#26804. (2) Yes: tombstone the split / drawer parameter keys withpane, each only after measuring that no live reader reads it on a surviving type (modalSizestays; it is read on any type).drawerSide/drawerWidthare also on objectstack-ai/objectstack#27153, so the PR body names that it lands that card's drawer half, whilebuttons.resetstays there. (3)object-form formTypestays out and goes to thedomain:ui` child, which the seat files.

  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment: seat ruling (2) narrowed after measurement · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-28T09:22Z · same claim (6465227713), same branch claude/project-thread-9k357q.

    Measured by the dev at start (main 6866e2e7). On form views, every read of the five split / drawer parameter keys sits under a retired type. But FormViewSchema is also the schema source of the React ObjectForm block contract (packages/spec/src/ui/react-blocks.ts dataProps). That block reads splitDirection, drawerSide and drawerWidth, and its formType: 'drawer' | 'split' survives here, because DrawerForm stays a caller container per the ruling. Tombstoning those three would also regenerate skills/objectstack-ui/references/react-blocks.md and make the PR governed (Tier H).

    Ruling (2), as applied: a key that a live reader reads on a surviving surface stays.

    File surface, replacing the claim's: packages/spec/src/ui/view.zod.ts (FormViewSchema.type, section.pane, splitSize, splitResizable) and its tests, the ADR-0087 disposition, the liveness ledger, regenerated baselines / forms / docs / ui manifest, examples/app-showcase/src/ui/views/task.view.ts, one changeset per touched published package.

    • ⛔ Not react-blocks.ts or the ObjectForm block keys.
    • ⛔ Not component.zod.ts object-form formType.
    • ⛔ Not ui/packages/** renderer branches.
    • ⛔ Not docs/adr/** or skills/**.

    Stop on breach and explain.

  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment 2: the Studio form-type choosers and the ui pins that assert the retired values · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-28T09:54Z · same claim (6465227713), same branch claude/project-thread-9k357q.

    Measured by the dev (static reading, to be confirmed with a ui run). The narrowing reaches ui/** outside the renderer branches in two ways.

    • Studio offers the retired values. Studio's view-create form offers all six form types (ui/packages/app-shell/src/views/metadata-admin/anchors.ts ~:289, default-schemas.ts ~:223). It writes config.type from that choice, so after this PR a split / drawer / modal pick produces a body the server refuses. That is a defect this PR would create.
    • ui tests pin the retired values as accepted. app-shell view-create-body.test.ts (~:97, :145) and plugin-form __tests__/formSectionGroupReference-7051.test.tsx (:478, ~:484) assert that the spec accepts them, and possibly two more test files that author pane.

    Ruling: A, widen. A defect this PR creates is fixed in this PR, the precedent being #26804, which fixed its own Studio inspector. The file surface gains:

    • the two Studio enum lists, narrowed to simple | tabbed | wizard;
    • every ui test whose assertion this narrowing makes false, re-pinned to the new truth (a retired value refused, never deleted to get green);
    • an @object-ui/app-shell changeset line, plus @object-ui/plugin-form if one of its tests moves only.

    The fences stand: ⛔ ObjectForm.tsx, ModalForm.tsx, SplitForm, react-blocks.ts, component.zod.ts, docs/adr/** and skills/** remain #27159's or out of scope. Stop on breach and explain.

  5. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment 3 · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-28T10:13Z · same claim (6465227713), same branch claude/project-thread-9k357q.

    The full build found one more Studio site that the narrowing makes false. It is the same class as amendment 2. ui/packages/app-shell/src/views/metadata-admin/package-schema.ts (~:118), getPackageForm(), is spec-typed and returns type: 'modal', which now fails TS2322.

    Ruling: it is in this PR's surface, respelled type: 'simple'. Its only reader, SectionedSchemaForm, branches on formType === 'tabbed' alone, so the render is unchanged. PackageFormDialog stays the dialog container. Any further app-shell site the build or type-check finds of the same class (a spec-typed literal of a retired value) is in the surface too, and is named in the PR body. The fences from amendment 2 stand.

  6. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 27155,
      "status": "done",
      "branch": "claude/project-thread-9k357q",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27229",
      "session": "session_01WGufziVeBj5ENSWqsDTaYe",
      "premise_still_valid": true,
      "summary": "FormViewSchema.type is simple|tabbed|wizard (default simple). split/drawer/modal are refused by name through enumWithRetiredValues, with prescriptions naming live replacements only (per objectstack-ai/objectstack#26804). sections[].pane, splitSize and splitResizable are retiredKey tombstones; splitDirection, drawerSide, drawerWidth and modalSize are kept for objectstack-ai/objectstack#27159. ADR-0087 kit: D2 form-view-presentation-types-removed (order 78, retiredAfter 18.2.0), D3 ui-form-view-type-layout-only, 3 RETIRED_KEYS rows, liveness rows, a JOIN row, and the pin form-view-type-layout-retirement.test.ts with a tree-scoped absence walk. Showcase respelled to tabbed/simple, with navigation.mode drawer on the list. Studio app-shell ripple fixed under claim amendments 2 and 3: the view-create and default-schemas enums, package-schema.ts modal->simple (TS2322), and 4 ui test pins re-pinned to the refusal.",
      "tests": "spec local 740 files, 22234 passed and 1 failed; the failure (view-metadata-schema splitSize vocabulary) was fixed and re-run 50/50. spec test:repo 82 files, 1355 passed. New pin 31/31; the absence walk named an injected pre-change task.view.ts. lint 2 files, 252 passed. showcase test 41 files, 505 passed. ui spec-reading sweep 370 passed, 1 skipped (7978 tests), VERDICT command-exit 0. ui scripts 175 files, 5019 passed. showcase build exit 0; with formViews.quick type 'modal' exit 2, invalid_value at formViews.quick.type with the prescription and the os migrate meta --from 17 sentence. Type-checks exit 0: spec typecheck (tests layer included), ui types, plugin-form, app-shell (tsconfig.test.json), console, showcase. Full pnpm build VERDICT command-exit 0, 116/116.",
      "gates": "dispatch-gates --commands derived 112 on cd275780d; all 112 :: exit 0. --ran: 112 derived, 112 run, 0 NOT-MEASURED, 0 UNRUN (exit 0). Re-run on edd4570f5 (one ui test file, 2 lines): check:type-check-debt, check:type-check-coverage, check:nul-bytes, check:test-source-alias, check:undeclared-dep-imports, check-comment-mask-adoption, check:issue-citations, plugin-form type-check, all exit 0. check-changeset-no-major with the PR event: exit 0. CI check-runs: pending at open.",
      "dogfood_battery": "cd275780d · VERDICT command-exit 0 · Test Files 348 passed and 3 skipped of 351 · Tests 2804 passed and 20 skipped of 2824 · no failures",
      "mcp_calls": "1 — subscribe_pr_activity (claude-code-remote; not a GitHub write tool). 0 GitHub MCP calls.",
      "api_writes": "3 relay strokes: pr_create (#27229), pr_request_reviewers (#27229, os-support-ai), comment (this report on objectstack-ai/objectstack#27155); plus git push x2",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: objectstack-ai/objectstack#27159 · ui object-form formType vocabularies still list split/drawer/modal (plugin-form index.tsx:295, types objectql.zod.ts:1017, console FormPage.tsx:259 FORM_SPEC_TYPES) and sdui.manifest object-form inputs carry splitSize/splitResizable · noted, not filed",
        "carrier: hotcrm seat · src/sales/views/lead.view.ts 3 form views (card reading L747/796/839 at 6c52f22) need the respell; not re-measured here (repo out of session scope) · noted, not filed"
      ]
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #27229 comment 6468327301

  8. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 3 · os-support-ai · 2026-10-28T12:17Z

    reading value
    PR #27229 merged through the queue at 2026-10-28T12:16Z, merge commit 14e9685fc9
    origin/main contains the merge commit (git merge-base --is-ancestor)

    Delivered (ruling A′, 6464210455; the spec half of the ADR-0050 cutover):

    • FormViewSchema.type is layout only: simple (default), tabbed, wizard. split, drawer and modal are refused at every door with a prescription that names live values only.
    • section.pane, splitSize and splitResizable retire with split. splitDirection, drawerSide and drawerWidth stay, because the React ObjectForm block still reads them.
    • Stored rows convert on read (D2 form-view-presentation-types-removed). Studio offers only the three layouts, and the package form's modal is now simple.

    Owed elsewhere: #27159 (renderer half, now unblocked), #27153 (drawerSide / drawerWidth / buttons.reset), objectstack-ai/hotcrm#2397 (hotcrm lead.view.ts). pm:dispatched is removed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:specDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions