Repository navigation
feat(spec)!: the action blocks spell the destructive variant danger, the word ActionSchema.variant uses - #26966
Conversation
The four action block rows (action:button, action:icon, action:group, action:menu and the containers' members) took the Button primitive's `destructive` and refused `danger`, while ActionSchema.variant, the declaration the action runner dispatches, says `danger`. The rows now take `danger` and refuse `destructive` with the rename in the enum's own error map. ADR-0087 D2 conversion page-action-block-variant-destructive-to-danger (retired from the load path, retiredAfter 18.2.0) rewrites stored rows and sources; D3 entry ui-page-action-block-variant-destructive-refused. Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
… `destructive` is gone Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
…r` input Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 2 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 148 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 701da0c562091acf7eaf60292ff3b920e277a8fc && git checkout 701da0c562091acf7eaf60292ff3b920e277a8fc
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ae16687ad430f4f9870ea5ba2bc9b63d6f41fc31 ea8465ed15e142c21d11849e0276173324f26056 && git checkout -B drift-repro ae16687ad430f4f9870ea5ba2bc9b63d6f41fc31 && git merge --no-ff ea8465ed15e142c21d11849e0276173324f26056
node scripts/docs-audit/affected-docs.mjs --json ae16687ad430f4f9870ea5ba2bc9b63d6f41fc31
|
Contract reviewServed-tier: Inputs read: card #26779 (body, triage 6448425754, claim 6454608654, os-dev report 6456191607), PR #26966 body and 22-file list, the net diff against Check-runs on the head at review time (59 runs): 24 ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentThe narrowing is judged against the published spec on
No path lets a stored page carry Implemented-by: VERDICT: PASS |
…e VS Code validator judges action block variants Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
…es its variant sentences Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
…-4h9cyt # Conflicts: # scripts/sdui-manifest.record.json
…ter merging main Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
… list successor, and spell the layout guide's Delete button danger The major-18 merge pin wants each conversion defined directly above the entry that follows it in MAJOR_18_CONVERSIONS. The layout guide's detail page fence still declared `variant: 'destructive'` on an action:button, which the row now refuses. Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
席位核对 · ACCEPT ·
|
席位核对 · ACCEPT (armed) ·
|
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40648482070 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40649482581 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U Contract-review-claim: Triage seat, under the gap rule (#27062), condition (b). The record on file names Generated by Claude Code |
Contract reviewServed-tier: Delta review on a moved head. The record on file (6456371394, Reviewed-by Check-runs on Delta since
|
…riants too, and member guidance says danger action:bar has no props row, but it draws each `actions` / `systemActions` member through the block renderers, which no longer read `destructive`, so a stored bar written that way fell back to a plain button with nothing to say so. The conversion now renames the bar's own `variant` and its members'. The container member `className` refusal and the member docblock named `destructive` as the red variant; they say `danger`. Claude-Session: https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF Co-authored-by: Claude <noreply@anthropic.com>
席位核对 · ACCEPT (armed) ·
|
Contract reviewServed-tier: Re-review after the FAIL record on Check-runs on Delta since
|
Requested by Yibo Wang · project thread
Fixes #26779
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Skills-docs: follow-up #27243 (
ui/content/docs/guide/layout.mdnow teachesvariant: 'danger'on anaction:button;check:doc-jsonandpage-width-padding-refusal-11318judge that fence against the rows, but no eval exercises an action block's variant)维护者速读
action:button/action:icon/action:group/action:menu及其成员)的variant把destructive改名为danger,与ActionSchema.variant同一个拼法;旧值保存时拒收并给出改名提示,存量页面由 ADR-0087 转换自动改写。danger、在区块里写destructive,两套方言让每个渲染器都要翻译一次;协议只留一个拼法(分诊裁决 6448425754)。variant: 'destructive'区块在下次保存时被拒(收窄,带迁移处方);存量page行在加载时被转换改写。回滚 = revert 本 PR。packages/spec/src/ui/component.zod.ts(ACTION_BLOCK_VARIANTS与actionBlockVariant)、packages/spec/src/conversions/registry.ts(pageActionBlockVariantDestructiveToDanger)、ui/packages/components/src/renderers/action/runner-variant.ts。pnpm --filter @objectstack/spec exec vitest run src/conversions/page-action-block-variant-destructive-to-danger.test.ts,预期 35 个用例全绿(六行接受danger、拒收destructive并给改名提示、存量行被改写)。What changes
Spec (
packages/spec/src/ui/component.zod.ts). The five rows that readBUTTON_PRIMITIVE_VARIANTS(ActionButtonPropsSchema,ActionIconPropsSchema, the shared group/menu member shape,ActionGroupPropsSchema,ActionMenuPropsSchema) now readACTION_BLOCK_VARIANTS = default | danger | outline | secondary | ghost | link, plusprimaryon the three rows that took it before.BUTTON_PRIMITIVE_VARIANTShad no other reader onmain8074feb6, so it is replaced, not kept beside. Each row builds its enum throughactionBlockVariant(subject, extra), whose error map answersdestructivewith the rename ontodanger(naming the key the author wrote) and leaves every other miss to the enum's own message. That is the established enum-value retirement shape (FORM_VIEW_LAYOUT_RETIRED,OBJECT_FORM_LAYOUT_RETIRED); it adds no.refine(), so no dropped-refinements row. The.describe()texts saydangerand what it does.Data at rest. ADR-0087 D2 conversion
page-action-block-variant-destructive-to-danger(toMajor: 18,retiredFromLoadPath: true,retiredAfter: '18.2.0', order 77). It rewritesproperties.varianton the four block nodes andvarianton eachaction:group/action:menumember, at every positionmapPageComponentsvisits. It also visitsaction:bar, renaming the bar's ownproperties.variantand thevariantof eachactions/systemActionsmember. The bar draws its members through the block renderers withmember.variant || properties.variant, so both spellings would reach a renderer, and the bar has no props row to refusedestructiveat save (round 3, after the delta review6464021995). Every other component (element:buttonkeeps the primitive'sdestructive) and every other value is left as stored. D3 entryui-page-action-block-variant-destructive-refused. One JOIN row inretired-key-removal-version.pin.test.ts(six refusals; the pin derives@objectstack/spec 18and--from 17fromretiredAfter).ui renderers.
runner-variant.tsnow holds two closed maps and neither readsdestructive:toRunnerVariantforwardsdanger | primary | secondary | ghost | linkas they are (and nothing fordefault/outline), andtoButtonVariantdrawsdangeras the primitive'sdestructiveandprimaryasdefault. The four renderers draw throughtoButtonVariant, and the group/menu dropdown items paint red ondanger. The designer inputs ofaction:buttonandaction:iconlistdangerin place ofdestructive, andsdui.manifest.jsonis regenerated (two enum values).UIActionSchema.variantfollows the rows by reference, so its doc comment is rewritten.The #26776 bridge is removed, not kept. It existed because stored and authored blocks said
destructivewhile the runner readsdanger. After this PR the rows refusedestructiveat save, a page's next save meets the component-props gate, and every data-at-rest seam (applyConversionsToStoredItemfor storedpagerows, the artifact door inside its declared-floor window,os migrate meta --writefor sources) replays the conversion, retired entries included. So no stored page reaches a renderer withdestructive, and AGENTS.md Prime Directive 12 leaves no room for a consumer-side alias kept "just in case".Authored values converted. No
examples/**,apps/**,packages/platform-objects/**,skills/**orcontent/docs/**source writesvariant: 'destructive'on an action block (measured with agit grepovervariant+destructiveat8074feb6; every hit there is a ReactButton/Alertprimitive or atype: 'button'component). The authored ones are inui/: the record detail views' code-built Delete entry for the⋯menu (RecordDetailView.tsx,plugin-detailDetailView.tsx), theaction-bar.tsxdoc example, and the test fixtures below.VS Code extension.
ui/packages/vscode-extension/src/providers/SchemaValidator.tsjudges the action block variants against the block rows (dangeraccepted,destructiveanswered with the rename;primaryon the rows that take it). Thebuttoncomponent's list, which is the Button primitive's and keepsdestructive, is untouched. The package is private, so it needs no changeset.Changeset
.changeset/26779-action-block-variant-danger.md:@objectstack/spec,@object-ui/components,@object-ui/types,@object-ui/plugin-detailminor, with the FROM → TO prescription, both declaration lines and theregisteredADR-0087 marker, plus a paragraph that supersedes the variant sentences of the pending #26665 entry.Tests
packages/spec/src/conversions/page-action-block-variant-destructive-to-danger.test.ts(35 cases): the six rows acceptdanger; refusedestructivewith the rename atvariant/actions.0.variant; CONTROL, another miss keeps the enum message; the stored-row seam rewrites all four nodes and a member alone (copy-on-write for the other); six controls left as stored; canonical page returns the same reference; idempotent; the authoring funnel does not replay it.component-report-items-action-members-typed.pin.test.ts(two members), uiaction-group-menu-inputs-11168.test.tsx(two members, same assertions:bg-destructiveandtext-destructive),action-variant-confirm-26665.test.tsx(the four blocks confirm through the destructive button ondanger; newtoButtonVariantrows; CONTROL rows thatdestructiveis no longer read), and onepins:sentence inregistry-inputs-spec-parity.test.ts.Acceptance notes
aliasesprescription".strictObject'saliasesmaps unknown KEYS to known ones; a renamed VALUE has no key to alias, so the prescription lives in the enum's error map, the shape the other enum-value retirements use.RecordDetailView.tsxandplugin-detailDetailView.tsx(their Delete entry would lose its red row once the menus paint ondanger),@object-ui/typesui-action.ts(doc comment of the by-reference type),sdui.manifest.json+scripts/sdui-manifest.record.json(the registry-change regeneration; the record'sobjectuiWorkspaceVersionmoves 18.1.0 → 18.2.0 because main's record trailed the version label), the D3 entry and the JOIN row (both red without them, as on the locale retirement).sys_deletefixturevariant: 'destructive': the header judges destructiveness byvariant === 'danger' || name === 'sys_delete', and that fixture is the by-name control.ActionPreview.tsxpreviews anActionSchema, not a block.destructivewhile the spec's ActionDef saysdanger, so a block-declared danger action confirms through a neutral button #26665 changeset..changeset/26665-action-block-destructive-confirm.md(not yet released) describes the bridge this PR removes ("dangerstays refused there"). It is left byte-identical to the merge base, because editing another card's pending note is the DELIBERATE CORRECTION class that keepscheck-empty-changesetred until a person confirms it. Instead, this PR's changeset carries a paragraph that explicitly replaces that entry's variant sentences in the same release and keeps its confirm-dialog behaviour (seat 1 ruling).pagerows and built artifacts in their window; a hotcrm source with adestructiveblock meets the refusal on its nextos validate.Verification
Readings on the pre-merge head
22846faeunless marked;mainwas then merged (17ecbb46, 28 commits, none touching a file this PR edits) and the spec artefacts and spec tests below were re-run on the merged head.Re-measure before any edit (main 8074feb)
A
safeParseprobe over the six rows:action:button,action:icon,action:group, the group member,action:menuand the menu member each REFUSEdanger("Invalid option: expected one of default|destructive|outline|secondary|ghost|link…") and ACCEPTdestructive. The premise held on all six.BUTTON_PRIMITIVE_VARIANTShad five readers, all action block rows, and no other.Spec
pnpm --filter @objectstack/spec build, thencheck:generated: 13/14 up to date,check:docsstale;--fixrewrotecontent/docs/references/ui/component.mdx, then 14/14 up to date. On the merged head17ecbb46: build +check:generated, all 14 up to date, nothing to commit.pnpm --filter @objectstack/spec typecheck: exit 0.pnpm --filter @objectstack/spec test: 739 files, 22139 tests passed (1 todo). Lock VERDICT command-exit 0.vitest run src/conversions src/migrations src/shared/retired-key-removal-version.pin.test.ts src/ui/component-report-items-action-members-typed.pin.test.ts: 29 files, 1054 tests passed.ui
--filter '@object-ui/app-shell^...' --filter '@object-ui/plugin-detail^...' --filter @objectstack/formula --filter @objectstack/client: VERDICT command-exit 0.vitest run packages/components/src/renderers/action+ the threepage-header-*tests +apps/console/src/__tests__/registry-inputs-spec-parity.test.ts: 40 files, 921 tests passed.type-checkon@object-ui/types,@object-ui/components,@object-ui/plugin-detail,@object-ui/app-shell: all four Done, VERDICT command-exit 0..d.ts: a scratch file assigning'destructive'and'danger'toUIActionSchema['variant']reds only the first (TS2322: Type '"destructive"' is not assignable to type '"default" | "link" | "primary" | "secondary" | "danger" | "ghost" | "outline" | undefined'); the file was then deleted.node scripts/gen-sdui-manifest-node.mjs: 106 components; the diff is the twodestructive→dangerinput enum values.Derived gates and dogfood
dispatch-gates.mjs --commands: 116 families. Run serially: 114 exit 0,spec check:skill-examplesandcheck:dual-build-cjs-loadsexit 3 (prerequisite not built). After the dogfood closure build both exit 0 (267 prose examples type-check; dual-build floors met).--ranreconciliation: 116 derived, 116 accounted for.--filter '@objectstack/dogfood^...'build, thenpnpm --filter @objectstack/dogfood test, one lock): VERDICT command-exit 1. Test Files 1 failed, 339 passed, 3 skipped (343); Tests 2 failed, 2752 passed, 20 skipped (2774). Both failures are intest/packaged-action-disabled-dispatch-live.dogfood.test.ts(acceptance 0 and acceptance 5/2). Run alone on the same head it passes 8/8, the load flake already recorded for that file; this diff touches no action-disable path.node scripts/check-nul-bytes.mjs: exit 0. No exported symbol is renamed or removed (BUTTON_PRIMITIVE_VARIANTSwas module-private), socheck-platform-checklistwas not owed.Human Minimum
Each item is one rule from
CONTRIBUTING.md › Human Minimum,
which links the AGENTS.md text that states it.
packages/specholds no runtime logic.pnpm lintpasses. (No formatter ran.pnpm lintis CI's run.)main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGufzeYWDZN6LkXji5ziLF