Skip to content

feat(spec): structured buttons + defaults config on FormViewSchema (#2998) - #3014

Merged
os-zhuang merged 2 commits into
mainfrom
claude/formviewschema-button-defaults-77q7fs
Jul 16, 2026
Merged

feat(spec): structured buttons + defaults config on FormViewSchema (#2998)#3014
os-zhuang merged 2 commits into
mainfrom
claude/formviewschema-button-defaults-77q7fs

Conversation

@os-zhuang

@os-zhuangos-zhuang commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

实现 #2998Track A:为 FormViewSchema 增加结构化的 buttons + defaults 配置(Track B —— 将 view 纳入 liveness ledger —— 按 issue 的排期约定另开专门 PR,不在本 PR 范围内)。

背景

objectui 侧的 ObjectForm 今天读取一组 spec 中不存在 的扁平表单键(showSubmit/submitText/showCancel/cancelText/showReset/initialValues,见 objectui#2545 与 docs/audits/2026-06-viewschema-property-liveness.md:25)。FormViewSchema 是 strip 模式容器,这些键在 .parse() 时被静默剥除 —— 正是 ADR-0078 禁止的 "parsed → silently inert" 形态。本 PR 按 issue 中的草图把这组渲染器自造键收编进协议。

变更内容

  • buttons(新增可选顶层键,紧邻 submitBehavior):submit / cancel / reset 三个动作按钮的 { show, label } 结构化配置。叶子 schema FormButtonConfigSchema(新导出)按 ADR-0089 D3a 使用 .strict(),拼错键(如把 submitText 写进 buttons.submit)会大声报错而不是消失;label 复用 I18nLabelSchema
  • defaults(新增可选顶层键):create 模式表单的初始字段值,按字段机器名(machine name)索引 —— 收编 objectui 的 initialValues
  • ADR-0078 约束的落地形态:本仓库对 FormViewSchema 没有运行时消费者,新增无人读取的可写面本身就是 parsed-but-inert。由于本 session 仓库范围仅限 framework,无法同批联动 objectui 渲染器,故按 issue 列出的 fallback 形态落地:两个键的 TSDoc 与 .describe() 均标注 [EXPERIMENTAL — NOT ENFORCED, #2998],直到 objectui 侧接线(objectui#2545)。该标记与 liveness ledger 的 experimental 正则(check-liveness.mtsMARKER_RE)匹配,Track B 入册时可直接归类为 experimental,不会挡 gate。
  • 纯增量:容器是 strip 模式,不改变任何既有键的形状 —— minor changeset,无需 tombstone。
  • 测试(view.test.ts 新增 6 例):解析往返、部分配置、strict 叶子对旧扁平键/拼错键的拒绝、experimental 标记断言;api-surface.json 重新生成(+2 个导出);自动生成的 content/docs/references/ui/view.mdx 同步再生(仅本变更相关的 hunk;gen:docs 顺带再生的无关陈旧文件已回退,未纳入)。

遗留的开放问题(维持现状,未动)

  • wizard 的 nextText/prevText 目前 spec 中并不存在,showStepIndicator 已在 spec —— issue 中标记为 open question,本 PR 不折叠进 buttons,留待 objectui 接线时一并定夺。
  • submitBehavior 在审计中被判定为 dead(无渲染器消费者,audit L20)—— 与新块相邻,建议在 objectui#2545 接线时一并布线或另行处置。

验证

  • pnpm test(turbo 全仓)126/126 任务全绿;spec 包 253 个测试文件 6861 例通过。
  • pnpm --filter @objectstack/spec build + gen:api-surface 通过,surface diff 仅 +FormButtonConfigSchema / +FormButtonConfig

Grounding: ADR-0078(escape hatch)、ADR-0089 D3a(strict 叶子)、ADR-0049/0050。Refs objectstack-ai/objectui#2545objectstack-ai/objectui#1763

Refs #2998(仅完成 Track A;Track B 另开 PR 跟踪,不要因本 PR 合并而关闭该 issue)。

🤖 Generated with Claude Code

https://claude.ai/code/session_013Ue47V8zZ5QhcYMPiRQDA7

…2998)
Track A of #2998: give the renderer-invented flat form keys ObjectUI's
ObjectForm reads today (showSubmit/submitText/showCancel/cancelText/
showReset/initialValues — objectui#2545) a real home in the protocol,
instead of being silently stripped by the strip-mode FormViewSchema
container (the "parsed -> silently inert" shape ADR-0078 prohibits).
- New optional `buttons` block: per-button `{ show, label }` for
submit/cancel/reset via a new exported FormButtonConfigSchema leaf,
`.strict()` per ADR-0089 D3a so typo'd keys error loudly.
- New optional `defaults` record: initial field values for create-mode
forms, keyed by field machine name (absorbs objectui `initialValues`).
- Both marked [EXPERIMENTAL — NOT ENFORCED, #2998] per ADR-0078's escape
hatch: the framework has no runtime consumer of FormViewSchema, so the
contract ships ahead of its ObjectUI consumer without a false promise.
The marker matches the liveness ledger's experimental regex, ready for
Track B (enrolling `view` in GOVERNED — separate PR per the issue).
- Purely additive (strip-mode container): minor changeset, no tombstone.
- Tests: parse round-trips, strict-leaf rejection of legacy flat keys,
experimental-marker assertion. api-surface.json regenerated (+2
exports); ui/view.mdx reference regenerated (scoped hunks only).
Refs ADR-0078, ADR-0089 D3a, objectui#2545, objectui#1763.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ue47V8zZ5QhcYMPiRQDA7
@vercel

vercelBot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 16, 2026 9:15am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests protocol:ui tooling size/m labels Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

97 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/cli.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/permissions/authorization.mdx(via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Conflict resolution: content/docs/references/ui/view.mdx (auto-generated)
regenerated via gen:docs on the merged tree; api-surface.json auto-merge
verified identical to regenerated output; json-schema.manifest.json
(disappearance ratchet, #3012, new on main) picks up +ui/FormButtonConfig.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Ue47V8zZ5QhcYMPiRQDA7
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude