Skip to content

refactor(ui)!: retire @object-ui/plugin-ai and its three node types - #27042

Merged
objectstack-fleet[bot] merged 20 commits into
mainfrom
claude/project-thread-26wk5s
Oct 28, 2026
Merged

objectstack-fleet[bot] merged 20 commits into
mainfrom
claude/project-thread-26wk5s

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Part of #25921 (the plugin-ai item only; the card's other items stay open).
Supersedes #26365 (its commits are carried here unchanged, then main merged and the changeset finished).
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Skills-docs: follow-up #27048 (the two skills/objectui/guides/* mentions, kept out of this PR by ruling 6439038287)

维护者速读

  • 改了什么:删除没有任何加载者的 @object-ui/plugin-ai 包;十个语言包删掉它的 ai.* 文案块;@object-ui/types 里它的类型/zod 镜像改为 @deprecated 的 never 墓碑,三个节点类型按名拒收并给出处方。changeset 改用整包操作数 @object-ui/plugin-ai#*。
  • 为什么改:执行 retire the zero-consumer surface: nine dead modules (2,211 LOC), plugin-ai, runner's publish flag, test-only reset helpers on public barrels, the providers trio, 122 dead i18n keys, root orphans #25921 的裁决 A(6398569691);ADR-0087 D9 的整包操作数已随 feat(adr-0087): retire a deleted published package whole (PACKAGE#*, D9 amendment) #26766 落地,按 6439038287 的「同意」改写 changeset 标记后门禁转绿。
  • 风险与回滚:npm 外部使用者未实测(changeset 的 BREAKING 说明覆盖);回滚即 revert 本 PR。check-empty-changeset 故意红着:合并 main 后待发的 26080 changeset 列着已删除的包,本 PR 删掉那一行,需要你确认。
  • 先看:.changeset/25921-retire-plugin-ai.md(整包标记与 FROM 行)、.changeset/26080-readme-contributing-links.md(删掉的一行)、ui/packages/types/src/zod/ai.zod.ts(拒收 arm 与墓碑)。
  • 两分钟验证:node scripts/check-adr-0087-registration.mjs --base origin/main,预期 exit 0,并打印 verified: @object-ui/plugin-ai#* (package, ui/packages/plugin-ai/package.json)。
  • 需要你做的:确认删掉 26080 changeset 里 '@object-ui/plugin-ai': patch 这一行(包已删除,留着会让 changeset version 失败),然后按 Tier H 批准(改动超过 3,000 行)。

What changes

  • Package deleted. ui/packages/plugin-ai/**, its pnpm-lock.yaml importer and its ui/vitest.config.mts alias.
  • Release group. Its entry leaves the fixed group in .changeset/config.json.
  • Locale packs. The ai.* block (ai.nlQuery.*, ai.formAssist.*, ai.recommendations.*) is deleted from all ten packs.
  • Types tombstones (ruling A). ui/packages/types/src/ai.ts keeps its nine exported names as @deprecated never aliases with the remedy, and AnySchema loses the three node members. In zod/ai.zod.ts the three arms become retiredNodeType() refusal arms, listed in AnyComponentSchema and not exported from the barrel. The eight published zod names stay exported as @deprecated z.never() schemas that accept nothing; when they leave the published face is docs/adr: a sunset rule for @deprecated tombstones — 574 tags (504 in packages/types, 640 'never' members) with no rule for when a tombstone leaves the authoring face #25912's sunset rule.
  • CLI. known-schema-types.ts loses the three keys.
  • Docs. ui/content/docs/plugins/plugin-ai.mdx and its meta.json entry. The package-table row now lives in the root CONTRIBUTING.md (main folded ui/README.md into it), and is removed there.
  • Changeset. .changeset/25921-retire-plugin-ai.md: @object-ui/types, @object-ui/i18n, @object-ui/cli minor, BREAKING. The ADR-0087 marker is not-required (runtime-export-retired @object-ui/plugin-ai#*), and the three per-export FROM lines are one line naming the package (FROM the package TO nothing, the TO text kept).
  • Pending changeset corrected. .changeset/26080-readme-contributing-links.md (landed on main after refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 was built) listed '@object-ui/plugin-ai': patch. A pending changeset naming a deleted package breaks changeset version, so that one line is deleted. Nothing else in that note changes.

Follow-up, not here (Tier H): skills/objectui/guides/project-setup.md and skills/objectui/guides/page-builder.md still name @object-ui/plugin-ai. They are governed, so they go in a separate PR after this one.

Forced test edits (each follows the deletion, none relaxes a check)

  • New pin ui/packages/types/src/__tests__/plugin-ai-retired-25921.test.ts: compile-time absence from AnySchema and the never names, the named refusal for each literal with its remedy, a firing control (button still accepted), a generic-path control for an unknown literal, and the eight zod names accepting nothing.
  • Deleted, because their subject left with the package: ai-zod-arms-10859.test.ts, ai-node-faces-agree-10874.test.ts, ai-zero-read-members-retired-8178.test.ts and the package's own test files.
  • zod-mirror-parity.test.ts, arm-named-export-8784.test.ts, any-component-emit-headroom-11573.test.ts, component-docs-retired-handler-keys-7340.test.ts, content-channel-family-d-9256.test.ts, content-channel-parser-tier-clause-10928.test.ts, silence-clause-parser-tier-closure-10981.test.ts, ai-insights-retired-8800.test.ts: rows and counts that named the three nodes, as in refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365.
  • ui/packages/cli/src/__tests__/registered-types-validate-ratchet-10859.test.ts: the "armed" case becomes a by-name refusal case with a generic-path control. ui/scripts/markdown-test-inputs.mjs follows: the entries that read the plugin-ai README go, and so does the notRead: ['packages/cli/README.md'] that main added to the cli entry (the scanner found that path only through the plugin-ai README's bare README.md segment, so the audit reports it stale once the README is gone).
  • Deletions-only ledgers lose their plugin-ai rows: clickableNonControlCensus-13461, iconOnlyButtonCensus-12143, runner-package-test-entry-3746, doc-version-claims; percent-storage-callers-11475 loses its plugin-ai exclusion set.
  • console-vite-alias-closure-4925.test.ts: its named negative control is now @object-ui/cli. select-type-check-scope.test.ts: its leaf-package fixture moves to plugin-markdown.
  • ui/scripts/__tests__/package-files-exist.test.ts: main's side taken on merge. test(floors, ui): one shared floor per ui package population, one catalog entry floor, all at about two thirds #26576 moved both floors to the shared published-package constant, which a retirement does not move, so refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365's hand-lowered floors are gone.

Tests

Readings at head 7040d92 (merge of main acc9c57)
  • pnpm --dir ui exec vitest run packages/types packages/i18n packages/cli: 511 files passed, 12453 tests passed, 13 skipped.
  • pnpm --dir ui exec vitest run scripts/ at 53dfa40: 178 files, 1 failed (markdown-test-inputs.test.ts, the stale notRead above), 5017 passed. Fixed in 7040d92; that file rerun: 17 / 17 passed.
  • type-check of @object-ui/types, @object-ui/i18n, @object-ui/cli (script names echoed): exit 0. pnpm --dir ui run type-check:scripts: exit 0.
  • Build: turbo run build with the root script's filters, 115 / 115 tasks.
  • Ablation of the new pin (from refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365, its test unchanged here): RetiredNLQueryNodeSchema deleted from AnyComponentSchema turns exactly the two nl-query cases red (2 failed, 15 passed of 17); restored, blob equals HEAD.

Acceptance notes

  • ADR-0087 predicate 2 and two code-string mentions. Classified with the gate's own maskComments and packageReference, ui/packages/types/src/zod/ai.zod.ts at this head names @object-ui/plugin-ai in code twice: both are the refusal remedy strings of the retired node arms (the text ruling A asks for). Every other mention in ui/packages/types/src/zod/*.zod.ts is a comment. Predicate 2 judges the package at the merge base, where all four mentions on main are comments, so the gate is green. The seat ruled to proceed as is.
  • Tracker number in runtime strings. Those refusal strings carry (objectstack#25921). AGENTS.md says runtime strings carry no tracker number (check:doc-authoring); that gate is not in this diff's derived set and nothing derived refused it, so the strings are left as built.
  • check-empty-changeset red by design. It refuses the one-line correction of .changeset/26080-readme-contributing-links.md (DELIBERATE CORRECTION class). The gate stays red until a maintainer confirms the correction on this PR.
  • External npm consumers of @object-ui/plugin-ai: NOT MEASURED; the changeset carries the FROM / TO line.
  • Leftover pre-merge notes under ui/.changeset/ still name @object-ui/plugin-ai; the root changesets config does not read that directory (ui/AGENTS.md), so they are untouched.
  • Unrelated plugin-ai mentions under packages/spec, packages/metadata-protocol and scripts/check-service-providers.mjs name the platform's own AI service plugin, not this package.

Verification

  • node scripts/check-adr-0087-registration.mjs --base origin/main: exit 0, verified: @object-ui/plugin-ai#* (package, ui/packages/plugin-ai/package.json).
  • pnpm changeset status: exit 0.
  • Lockfile: pnpm install --frozen-lockfile exit 0 after the merge, and pnpm install --lockfile-only leaves pnpm-lock.yaml byte-identical (0 plugin-ai mentions).
  • node scripts/pm/dispatch-gates.mjs --ran: 56 derived, 56 run, 0 NOT-MEASURED. Red: check-empty-changeset --base origin/main (by design, above) and the first vitest run scripts/ (fixed, above). check:dts-closure, check:dual-build-cjs-loads and check:lean-entry-closure exit 3 or 1 before the build and 0 after it.
  • node scripts/check-platform-checklist.mjs --changed-from origin/main: 0 anchored files in the change set.
  • dispatch-gates --tier: no path-derived mandate (TIER_DEFAULT). Changed lines 7568 (+439 / −7129): over the 3,000-line threshold, so this lands by an authorized approval.
  • Full dogfood on the final head: reading goes in the card's os-dev report.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes (CI-owned run).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

Generated by Claude Code

claude added 19 commits October 26, 2026 22:18
…(WIP)

Part of the plugin-ai retirement (ruling A on the zero-consumer card).

Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>
…puts and the types pins (WIP)

Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>
…he new retirement pin (WIP)

Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>
… ledgers after the plugin-ai retirement (WIP)

Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>

# Conflicts:
#	scripts/sdui-manifest.sources/i18n.json
#	scripts/sdui-manifest.sources/types.json
…plugin-ai retirement

Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBDBR9oS1MNUcjBVXds5D6
Co-authored-by: Claude <noreply@anthropic.com>

# Conflicts:
#	.changeset/25831-object-ui-18-1-to-merge.md
#	content/docs/protocol/backward-compatibility.mdx
#	scripts/publish-smoke-pack.mjs
#	scripts/sdui-manifest.sources/i18n.json
#	scripts/sdui-manifest.sources/types.json
#	ui/packages/plugin-ai/CHANGELOG.md
#	ui/packages/plugin-ai/package.json
#	ui/scripts/__tests__/package-files-exist.test.ts
…-26wk5s

# Conflicts:
#	ui/QUICK_REFERENCE.md
#	ui/README.md
#	ui/packages/plugin-ai/README.md
#	ui/scripts/__tests__/package-files-exist.test.ts
#	ui/scripts/markdown-test-inputs.mjs
The runtime-export-retired marker names the package as `@object-ui/plugin-ai#*`
(ADR-0087 D9 whole-package operand) and its three per-export FROM lines become
one line naming the package. Merging main brought two more mentions of the
deleted package: the pending README-links changeset's patch line (a pending
changeset naming a deleted package breaks `changeset version`) and the
CONTRIBUTING.md package-table row that moved there from ui/README.md.

Claude-Session: https://claude.ai/code/session_01JQwxbYonqfPMAts3ErwZAK
Co-authored-by: Claude <noreply@anthropic.com>
Main added `notRead: ['packages/cli/README.md']` to the cli ratchet's
markdown-input entry because the scanner resolved the bare `README.md`
segment of the plugin-ai README path against that package. With the
plugin-ai README gone the scanner no longer offers it, and the audit
reports the entry stale.

Claude-Session: https://claude.ai/code/session_01JQwxbYonqfPMAts3ErwZAK
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat note · contract review owed · seat domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-28T03:10Z

This PR declares Clause-②: no (narrowing) and Metadata-protocol: narrowed, so it owes a CONTRACT_REVIEW_TIER contract review over the whole diff outside the prose surfaces before any approval or queue (references/contract-review.md). This seat cannot run that tier: the ceiling model has been unavailable to the fleet since 2026-10-27, so the seat runs at TIER_DEFAULT under the quota exemption. Per the same reference it does not review at a lower tier, and it hands the review to triage.

Contract-review-handoff: triage — CONTRACT_REVIEW_TIER unavailable (ceiling model out for the fleet since 2026-10-27, seat runs at TIER_DEFAULT, 2026-10-28T03:10Z) · head 7040d92f78f504b1ef037d8451106c0be452f375

Inputs for the reviewer:

No reviewer is requested and the PR stays draft until a same-form PASS is on file and the seat's Tier H record is posted (#26617).


Generated by Claude Code

…-26wk5s

# Conflicts:
#	pnpm-lock.yaml
#	ui/packages/plugin-ai/package.json
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat note · contract review hand-off renewed · seat domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-28T12:13Z

The hand-off line in 6459640213 named head 7040d92f. The dev then merged origin/main (ff079cc0, 07:34Z), so that line went stale and triage would correctly not take it. The seat checked the merge: the file set is unchanged and every file's +/- lines are identical to 7040d92f, except ui/packages/plugin-ai/package.json (the deletion now also carries main's #27072 dev-dependency bump) and pnpm-lock.yaml (only the 49-line ui/packages/plugin-ai importer removed). The reviewer's inputs in 6459640213 stand unchanged.

Contract-review-handoff: triage — CONTRACT_REVIEW_TIER unavailable (ceiling model out for the fleet since 2026-10-27, seat runs at TIER_DEFAULT, 2026-10-28T12:13Z) · head ff079cc066b82261e0827f995c83d075302f6798

Draft on purpose. This PR is Tier H. While #26617 is open, relay pr_ready on a Tier H diff auto-requests the governed approvers, and #26617 forbids putting approvers in front of a Tier H PR before a contract review PASS and the seat ACCEPT. So the PR cannot be readied before the review. #27062's "the PR is ready (not draft)" precondition does not fit this case; the hand-off line above is condition (a), and this seat asks triage to take the review on the draft.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Contract-review-claim: session_01AavokzJ5DndAwitDXvKy4U · head ff079cc066b82261e0827f995c83d075302f6798 · 2026-10-28T12:16Z

Triage seat, taking the hand-off that names this head (Contract-review-handoff: triage …). ⚠️ Triage missed this hand-off for several rounds: its scan, rebuilt at R720, skipped draft PRs and did not read hand-off lines. That is now fixed. The review runs at CONTRACT_REVIEW_TIER.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: ff079cc066b82261e0827f995c83d075302f6798
Local-runs: none
Scope: .changeset/25921-retire-plugin-ai.md, .changeset/26080-readme-contributing-links.md, .changeset/config.json, pnpm-lock.yaml, ui/vitest.config.mts, ui/content/docs/plugins/meta.json, ui/packages/cli/src/utils/known-schema-types.ts, ui/packages/cli/src/__tests__/registered-types-validate-ratchet-10859.test.ts, ui/packages/components/src/__tests__/clickableNonControlCensus-13461.test.ts, ui/packages/components/src/__tests__/iconOnlyButtonCensus-12143.test.ts, ui/packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts, ui/packages/plugin-ai/package.json, ui/packages/plugin-ai/tsconfig.json, ui/packages/plugin-ai/tsconfig.test.json, ui/packages/plugin-ai/vite.config.ts, ui/packages/plugin-ai/src/AIFormAssist.tsx, ui/packages/plugin-ai/src/AIRecommendations.tsx, ui/packages/plugin-ai/src/NLQueryInput.tsx, ui/packages/plugin-ai/src/index.tsx, ui/packages/plugin-ai/src/useAiTranslation.ts, ui/packages/plugin-ai/src/AIRecommendations.layoutCarouselRetired-10330.test.tsx, ui/packages/plugin-ai/src/AIRecommendations.rendersEveryItem-8178.test.tsx, ui/packages/plugin-ai/src/aiComponents.i18n-10232.test.tsx, ui/packages/plugin-ai/src/registrationInputs-8178.test.ts, ui/packages/types/src/ai.ts, ui/packages/types/src/index.ts, ui/packages/types/src/zod/ai.zod.ts, ui/packages/types/src/zod/index.zod.ts, ui/packages/types/src/__tests__/plugin-ai-retired-25921.test.ts, ui/packages/types/src/__tests__/ai-insights-retired-8800.test.ts, ui/packages/types/src/__tests__/ai-node-faces-agree-10874.test.ts, ui/packages/types/src/__tests__/ai-zero-read-members-retired-8178.test.ts, ui/packages/types/src/__tests__/ai-zod-arms-10859.test.ts, ui/packages/types/src/__tests__/any-component-emit-headroom-11573.test.ts, ui/packages/types/src/__tests__/arm-named-export-8784.test.ts, ui/packages/types/src/__tests__/component-docs-retired-handler-keys-7340.test.ts, ui/packages/types/src/__tests__/content-channel-family-d-9256.test.ts, ui/packages/types/src/__tests__/content-channel-parser-tier-clause-10928.test.ts, ui/packages/types/src/__tests__/silence-clause-parser-tier-closure-10981.test.ts, ui/packages/types/src/__tests__/zod-mirror-parity.test.ts, ui/scripts/__tests__/console-vite-alias-closure-4925.test.ts, ui/scripts/__tests__/doc-version-claims.test.ts, ui/scripts/__tests__/percent-storage-callers-11475.test.ts, ui/scripts/__tests__/runner-package-test-entry-3746.test.ts, ui/scripts/__tests__/select-type-check-scope.test.ts, ui/scripts/markdown-test-inputs.mjs (prose faces read, not reviewed: CONTRIBUTING.md, ui/content/docs/plugins/plugin-ai.mdx, ui/packages/plugin-ai/README.md, ui/packages/plugin-ai/CHANGELOG.md, ui/packages/plugin-ai/LICENSE, ui/packages/types/src/zod/README.md) + docs/adr/0087-metadata-protocol-upgrade-contract.md (D9 and its two 2026-10-27 amendment notes), scripts/check-adr-0087-registration.mjs (verifyWholePackageRetired, packageReference, the WP battery), scripts/check-empty-changeset.mjs (scanForeign, FOREIGN_TWO_CLASS_LINES), .github/workflows/pr-automation.yml (Check Changeset steps 10, 11, 13), pnpm-workspace.yaml, ui/packages/types/src/zod/tombstone.zod.ts (retiredNodeType), ui/packages/types/src/zod/cloud.zod.ts, ui/packages/types/src/zod/complex.zod.ts, ui/packages/types/src/zod/data-display.zod.ts (the three refusal-arm precedents), ui/packages/cli/src/utils/known-type-case-suggestion.ts, ui/packages/cli/src/utils/union-arm-diagnostics.ts, skills/objectui/guides/project-setup.md, skills/objectui/guides/page-builder.md, ui/.changeset/13464-declare-side-effects.md, ui/.changeset/13465-react-peer-plugin-ai.md, ui/.changeset/25685-one-react-line.md, ui/AGENTS.md, AGENTS.md, scripts/check-doc-authoring.mjs (ROOTS), ui/scripts/vitest-invocation-guard.mjs, scripts/release-verify-npm.mjs, packages/spec/src/system/core-services.zod.ts, packages/metadata-protocol/src/protocol.ts, scripts/check-service-providers.mjs, and ui/packages/plugin-ai/package.json as it stands at the merge base e6e41998a8d4543f5935e7c45145dfc3d6fe0e26.

Inputs read in full: card #25921 body and all 27 comments (ruling A is the transferred comment 6407925660, formerly 6398569691 on objectui#13453; dispatch order 6458637853, claim 6458680506, os-dev report 6459593681); PR #27042 body, file list (61 paths) and net diff against main at this head; the 57 check-runs on this head (all completed, none pending); ruling 6439038287 on PR #26365 and the ADR-0087 D9 text #26766 landed (4bce21da81). The seat's TIER_DEFAULT notes (6459640213, 6468695894) are read as claims and re-derived below. Check-run verdicts on this head: 48 success, 8 skipped by selector, 1 failure — Check Changeset, whose steps read: 9 Require a changeset success, 10 Reject an empty-frontmatter changeset added by this PR FAILURE (annotation: .changeset/26080-readme-contributing-links.md exists on the merge base and was not added by this PR … DELIBERATE CORRECTION — … say so on the PR and get it confirmed), 11 Require an ADR-0087 disposition on a declared-breaking changeset success (annotation prints the runtime-export-retired exemption of .changeset/25921-retire-plugin-ai.md), 13 Guard against accidental major bumps success. The job log blob is not reachable from this container (403 at the storage redirect); the step conclusions and the check-run annotations are the gate verdicts read.

① Derived judgments

  1. @object-ui/plugin-ai leaves the workspace and the npm line at 18.2.0 — RIGHT. At the merge base the manifest is version 18.2.0, not private, types ./dist/index.d.ts, and the only src/index.* is src/index.tsx (D9's amended mapping). The only package.json naming it at the base is its own; ui/apps/console/src/register-plugins.ts and vite.config.ts never named it. At HEAD: no manifest carries the name (git grep over *package.json: none), pnpm-workspace.yaml names only globs, the fixed group in .changeset/config.json loses exactly its one line, the ui/vitest.config.mts alias line goes, and pnpm-lock.yaml loses exactly the 49-line importer with zero plugin-ai mentions left.
  2. The zod face: the three literals go from accepted arms to named refusals — RIGHT. index.zod.ts replaces AIComponentSchema in AnyComponentSchema with RetiredAIFormAssistNodeSchema, RetiredAIRecommendationsNodeSchema, RetiredNLQueryNodeSchema, each retiredNodeType(literal, PLUGIN_AI_RETIRED): one custom issue at ['type'] whose text names the literal, the retirement and the remedy ("Remove the node from the page; there is no replacement node type"), with .catchall(z.unknown()) so the refusal is exactly one issue. The arms are module exports but deliberately not on the index.zod.ts barrel (pin suite 4 proves absence with a lit control). Shape identical to cloud.zod.ts#RetiredCloudPlanStatusNodeSchema, complex.zod.ts#RetiredKanbanNodeSchema, data-display.zod.ts#RetiredHtmlNodeSchema. Both faces refuse: the tolerant safeValidateSchema (pin suites 1–3, with a surviving-arm control and a generic-path control) and the strict validateAuthoredDocument (the CLI ratchet's rewritten case, one custom issue at type naming the package, plus a generic-path control).
  3. The eight published zod names stay exported as @deprecated z.never() tombstones — RIGHT per ruling A's tombstone rule (@deprecated + never, remedy in the text; sunset waits for docs/adr: a sunset rule for @deprecated tombstones — 574 tags (504 in packages/types, 640 'never' members) with no rule for when a tombstone leaves the authoring face #25912). Pin suite 4 proves each accepts {}, a stale node and a string with a message naming the retirement.
  4. The TypeScript face: nine names become never, AnySchema loses three members — RIGHT. ai.ts keeps every exported name as @deprecated never with the remedy; index.ts drops the three from AnySchema and the now-unused import; compile-time pins (Extract on the three literals is never, button still selectable, an annotated literal is @ts-expect-error). No code in the tree names the three literals outside ai.ts, the zod module, the CLI list and tests.
  5. @object-ui/cli: KNOWN_SCHEMA_TYPES loses ai-form-assist, ai-recommendations, nl-query — RIGHT. The list feeds known-type-case-suggestion.ts and union-arm-diagnostics.ts; with the keys gone the CLI neither suggests the retired spellings nor lists them as known, and the by-name refusal arms carry the remedy on the diagnostics path. The ai:feedback / ai:input / ai:suggestion family stays, as it should (a different plugin).
  6. @object-ui/i18n: the ai.* block leaves all ten packs — RIGHT. Each locale diff is one deleted ai: { … }, block and zero added lines (ar 35, de 27, en 31 incl. its 4 comment lines, es 29, fr 29, ja 27, ko 27, pt 29, ru 31, zh 27 — the spread is CLDR plural categories). TranslationKeys (typeof en) narrows by those keys; git grep finds no reader of ai.nlQuery.* / ai.formAssist.* / ai.recommendations.* left in ui/. Declared in the changeset.
  7. ADR-0087 disposition not-required (runtime-export-retired @object-ui/plugin-ai#*) against D9 as amended by feat(adr-0087): retire a deleted published package whole (PACKAGE#*, D9 amendment) #26766 — RIGHT. Predicate 1 (retired-from-entry, about the package): base — workspace member, not private, entry maps via src/index.tsx; HEAD — no manifest of that name, no literal directory glob in pnpm-workspace.yaml, not in any fixed group. Predicate 2 (no-metadata-surface, read at the merge base by D9's own text): the package held no *.zod.ts, no packages/spec/src/contracts/ file and no object definition; every mention of @object-ui/plugin-ai in a metadata surface outside it at the base is a comment span (ai.zod.ts lines 14, 20, 33, 57; index.zod.ts line 444); packages/spec/src/system/core-services.zod.ts line 72 names the platform's plugin-ai service-slot placeholder, in a comment, unrelated to this package. Predicate 3 (from-operands-named): the body carries one FROM \@object-ui/plugin-ai` TO nothingline and no per-export FROM line. The gate's step 11 is green on this head. **The seat's step-3 call:** at HEADai.zod.tsnames the package in code twice — thePLUGIN_AI_RETIREDremedy string and theretiredExporttext. Judged RIGHT to proceed: predicate 2 reads the merge base by D9's wording ("read at the base because the operand is gone at HEAD"); neither string is an import specifier or any surfaceobjectstack migrate metacould rewrite; and the strings are exactly the "refused by name with a remedy" ruling6439038287chose overregistered`. A predicate that refused the remedy text would refuse the ruling itself.
  8. The one-line correction of .changeset/26080-readme-contributing-links.md — RIGHT as content: the note's prose is unchanged and only '@object-ui/plugin-ai': patch leaves its frontmatter. Changesets refuses a release for a package absent from the workspace (the exact error was reproduced on refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365's thread: Found changeset 26080-readme-contributing-links for package @object-ui/plugin-ai which is not in the workspace), so leaving the line in would break changeset version. The README edit that note described for this package left with the package. No other root changeset names the package. The confirmation question is ③.
  9. Every reader of the deleted package is gone — RIGHT, with the two ruled exceptions. git grep over the head tree (lockfile excluded) finds the package name only in: CHANGELOGs and content/docs/releases (history, never hand-edited), the ADR's amendment notes and the gate's self-test comment (they name it as the first case), comments and the pin/census tests that document the retirement, this PR's changeset, three pre-merge notes under ui/.changeset/ (no config.json there; ui/AGENTS.md says the root config does not read it; check-adr-0087-registration and check-empty-changeset list .changeset only), two stale measurement comments quoting cd packages/plugin-ai (ui/scripts/vitest-invocation-guard.mjs and its test, scripts/release-verify-npm.mjs timing table) which read nothing, and the two governed skills guides skills/objectui/guides/project-setup.md:75 and page-builder.md:328 that ruling 6439038287 keeps for the follow-up (skills/objectui guides still teach @object-ui/plugin-ai, a package retired by #25921 (PR #27042) #27048). No tsconfig, workflow, turbo, package.json, docs page, console registration or examples reader remains; Check Documentation Links is green with plugin-ai.mdx and its meta.json entry gone.
  10. Forced test edits — RIGHT, none relaxes a check: ledgers lose only their plugin-ai rows (component-docs-retired-handler-keys total 31 to 29, content-channel-family-d 31 to 30, EXPECTED_MIRROR_PAIRS down by the seven pairs that left MIRRORS); console-vite-alias-closure swaps its named negative control to @object-ui/cli; select-type-check-scope to plugin-markdown; markdown-test-inputs.mjs drops the two entries that read the deleted README and the notRead: ['packages/cli/README.md'] that existed only through that README's bare README.md segment; the CLI ratchet's "armed" case becomes a by-name refusal case with a control; percent-storage-callers loses the exclusion set for files that no longer exist. Test UI 1–16/16, Type Check UI and Lint UI are green on this head.
  11. CONTRIBUTING.md row removal — RIGHT (prose, read): main's docs: fold the ui/ top-level docs into the root README, ROADMAP and CONTRIBUTING (#26080 slice 1) #27001 folded the ui/README.md package table there; the row for a deleted package goes.

② Semver level

.changeset/25921-retire-plugin-ai.md: @object-ui/types minor, @object-ui/i18n minor, @object-ui/cli minor; ! in the title; a BREAKING banner; the removed names listed per package; the FROM → TO line. Matches what the diff publishes: types (nine never names, three members off AnySchema, eight z.never() names, three refusal arms), i18n (ai.* gone from ten packs), cli (three keys off the known list). @object-ui/plugin-ai cannot be bumped (deleted; its line is the FROM/TO). @object-ui/components and ui/scripts change tests only; ui/content/docs and root CONTRIBUTING.md publish nothing. Level: ruling A on the card says in so many words "Changeset minor with the removed names and the breaking note, per the version policy" and the lane's standing policy reads "each changeset is minor with the removal named, never major"; all three packages sit in the same fixed group. check-changeset-no-major (step 13) is green: a declared protocol narrowing owes minor, and it gets minor.
Clause-②: no (narrowing) on the PR body and at the start of a line in the changeset body, beside Metadata-protocol: narrowed — coherent (no narrowed-without-arm contradiction), and true to the diff: nothing widens; three node types, nine type names, eight zod names, three CLI keys and one locale block leave the accept set, and a package leaves the registry.
Metadata-protocol: narrowed — right: three node literals become refused arms on the zod face (release minor).

③ Boundary flags

  • Dev deviation 1 — two code-string mentions of the package in ai.zod.ts at HEAD (step 3 stop-and-report), seat ruled proceed. ANSWERED: right, see ① item 7. No action.
  • Dev deviation 2 — (objectstack#25921) inside the runtime refusal strings. AGENTS.md: "Runtime strings — refusal prose, prescriptions, anything an author is shown — carry no tracker number (pnpm check:doc-authoring)". The named gate's ROOTS are .claude, docs, skills, content, so it never reads ui/packages/types, which is why nothing derived refused it. The ui refusal-arm population already carries trackers (cloud.zod.ts "(objectui#12954)", data-display.zod.ts "(objectui#13449)"), so this is a population convention, not a new deviation. should-fix: drop (objectstack#25921) from PLUGIN_AI_RETIRED and the retiredExport text (the lesson is already in the words), and re-point pin suite 4's toContain('objectstack#25921') at the retirement text; a population sweep is a separate card. Not blocking.
  • Dev deviation 3 / open question 1 — the one-line deletion in the pending .changeset/26080-readme-contributing-links.md. Content RIGHT (① item 8); recommendation A is the only one that keeps changeset version runnable. ESCALATED to the maintainer: the [finding] the skip-changeset label suppresses the DELIBERATE-CORRECTION refusal whose own text says 「no label and no diff shape makes that safe」 — declared contract against enforced behaviour #18375 rule (check-empty-changeset.mjs, FOREIGN_CORRECTION_REMEDY: "say so on the PR and get it confirmed … this gate stays red either way") wants the confirmation ON THIS PR. The PR body says so and names the note and the line, which is the dev's half. No confirmation is on refactor(ui)!: retire @object-ui/plugin-ai and its three node types #27042: its three comments are the seat's hand-off notes and triage's claim. The only confirmation on record is second-hand and elsewhere — comment 6460230552 on the superseded PR refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 says "Steve confirmed the edit in the project thread with 「同意」 at 2026-10-28T03:32Z". A relayed thread word on another PR is not a confirmation on this PR. Before landing, the maintainer (or the seat quoting the maintainer's verbatim word, time and place) writes the confirmation on refactor(ui)!: retire @object-ui/plugin-ai and its three node types #27042; the Check Changeset red stays red by design and must not be routed around with skip-changeset (which would also be a false declaration here, since the PR ships a real changeset). Landing condition, not a defect of the diff.
  • Dev deviation 4 — CONTRIBUTING.md row removed (forced by main's docs: fold the ui/ top-level docs into the root README, ROADMAP and CONTRIBUTING (#26080 slice 1) #27001). ANSWERED: right.
  • Dev deviation 5 — merge resolution (ui/README.md, ui/QUICK_REFERENCE.md keep main's deletion; package-files-exist.test.ts takes main's UI_PUBLISHED_PACKAGE_FLOOR; markdown-test-inputs.mjs drops the stale notRead). ANSWERED: right; the shared constant is not touched by this diff and Test UI is green on it.
  • Dev deviation 6 — PR body folds the template headings into the os-dev order. Not a contract matter.
  • Out-of-scope finding — skills/objectui/guides/project-setup.md and page-builder.md still install and list the package. ANSWERED: kept out by ruling 6439038287; Skills-docs: follow-up #27048 is in the form the claim template fixes (follow-up #N, the value first after the colon; the parenthetical is explanation), skills/objectui guides still teach @object-ui/plugin-ai, a package retired by #25921 (PR #27042) #27048 is open and names exactly those two files and the three retired literals, and git grep confirms they are the only skills/** readers. Right and truthful.
  • Out-of-scope finding — three ui/.changeset/ pre-merge notes name the package. ANSWERED: right that nothing reads them (no config.json under ui/.changeset; every changeset reader in scripts/ and the workflows lists .changeset only; ui/AGENTS.md forbids adding there). Cosmetic leftovers outside this card; no action owed here.
  • Reviewer's own flags. (a) Tier H: +439 / −7129 is over the 3,000-line line and the PR is a draft on purpose (fleet-write: relay pr_create asks the governed approvers to review a Tier H draft before any contract review exists, so an approver can approve and merge it unreviewed (#26566, #26570) #26617); it lands only by an authorized human approval after this record and the seat ACCEPT — stated, not re-judged. (b) #26365 is closed (2026-10-28T06:15Z) with this PR's title, so one PR carries the item. (c) Part of #25921, not Fixes: the card's other items stay open — right (PR-body guards green). (d) The changeset's "objectui check no longer lists the three literals as known component types" is loose wording for "no longer knows or suggests them"; the behaviour it describes is true. No action.

④ Design judgment

The narrowing, read against the published spec on main (ui/packages/types/src/ai.ts, zod/ai.zod.ts, zod/index.zod.ts, cli/src/utils/known-schema-types.ts, the ten locale packs, .changeset/config.json) and the code that delivered it (ui/packages/plugin-ai/src/* at the merge base):

  • Declared-and-not-delivered, retired rather than narrowed at the consumer. On main the three literals are accepted by both validation faces, typed on AnySchema, listed as known by the CLI, and delivered by exactly one package that nothing in the workspace loaded: the console registered it neither eagerly nor lazily, so a page carrying one of the literals validated clean and rendered the OBJUI-001 "Unknown component type" panel. That is the implementation gap the ⛔ rule names. The PR takes the "retired" branch: the implementation (package), the declarations (TS names, zod arms, CLI keys) and the strings (locale block) leave together, by ruling A, and the consumer is told by name what happened and what to do. Nothing stays declared while being refused somewhere downstream.
  • The spec's own refusal is made real, by name, on both faces. Deleting the arms would already refuse, but with the union's remedy-free Invalid input; keeping retiredNodeType() arms inside AnyComponentSchema turns a stale { "type": "nl-query" } into one custom issue at type with the remedy, on the tolerant face and on the strict authoring face the CLI judges through. The arms are kept off the barrel so nothing parses against a refusal. The published mirror names stay importable as never / z.never() tombstones until docs/adr: a sunset rule for @deprecated tombstones — 574 tags (504 in packages/types, 640 'never' members) with no rule for when a tombstone leaves the authoring face #25912's sunset rule, so an upgrading consumer reads a deprecation instead of a TS2305. The pin test carries a firing control (button accepted), a non-vacuity control on the type instrument, and a generic-path control (an unknown literal gets no remedy text), and the seat's ablation on the unchanged refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 arms turned exactly the two nl-query cases red.
  • Attempts to break it. (1) A host that kept its own copy of the component and registered it under nl-query now has its pages refused by objectui validate: the FROM → TO line names the remedy (register under its own type key), and ruling A accepted this over wiring the package in. (2) D9 predicate 2 at HEAD: the two remedy strings are not metadata the protocol could convert, and D9 reads the base by its own text; the gate is green by design, not by accident. (3) TranslationKeys narrows: declared for i18n; no in-repo reader. (4) AnySchema['type'] exhaustiveness: no code switches on the three literals. (5) KNOWN_SCHEMA_TYPES consumers (known-type-case-suggestion, union-arm-diagnostics): with the keys gone the CLI suggests nothing for the retired spellings, and the refusal arms supply the remedy instead — consistent. (6) The lockfile: only the importer leaves, zero mentions remain, Validate Package Dependencies green. (7) The pending 26080 note: restoring the line breaks changeset version; the correction is necessary and minimal. (8) Readers outside ui/: the platform's own plugin-ai service-slot placeholder in packages/spec, packages/metadata-protocol and scripts/check-service-providers.mjs is a different thing, in comments, correctly untouched.
  • Findings. should-fix: the tracker number in the two runtime refusal strings (③ deviation 2). No must-fix.

Implemented-by: claude/project-thread-26wk5s
Reviewed-by: session_01AavokzJ5DndAwitDXvKy4U

VERDICT: PASS


Generated by Claude Code

@os-zhuang

Copy link
Copy Markdown
Contributor

同意删除

@os-zhuang

Copy link
Copy Markdown
Contributor

确认删掉 .changeset/26080-readme-contributing-links.md 里 '@object-ui/plugin-ai': patch

@objectstack-fleet

objectstack-fleet Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor Author

维护者速读(席位终稿)

席位意见:契约复核 PASS(6469104529,CONTRACT_REVIEW_TIER,head ff079cc0,must-fix 无);26080 删行已在本 PR 上得到维护者确认(6469258151「同意删除」、6469272336,2026-10-28T12:42Z)。同意落地。

席位核对

ACCEPT · seat domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · head ff079cc0 · 2026-10-28T13:03Z

  1. Shape: Part of #25921 (supersedes refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365; the card stays open for its other items); 61 files, +439/−7129. A trial merge with origin/main 9ff8154c is clean.
  2. Premise measured: the package has no loader on main; the D9 whole-package operand @object-ui/plugin-ai#* verifies (the review re-derived all three predicates). The 26080 one-line deletion is required: Changesets refuses a release line for a package absent from the workspace.
  3. Gates / check-runs: on ff079cc0: 48 success, 10 skipped, Check Changeset red by design (the [finding] the skip-changeset label suppresses the DELIBERATE-CORRECTION refusal whose own text says 「no label and no diff shape makes that safe」 — declared contract against enforced behaviour #18375 foreign-correction class, which stays red even after confirmation; not a required status check on main). Every required check (Type Check UI, Test UI, Lint UI, Build & E2E UI, the core checks, Governed Surface Queue Guard) is green.
  4. Accepted deviations: the review's one should-fix (drop (objectstack#25921) from the two runtime refusal strings in ui/packages/types/src/zod/ai.zod.ts and re-point pin suite 4) does not ride this PR, so the PASS stays pinned to its head. The seat files it as a follow-up after the merge.
  5. Maintainer confirmation: written on this PR at 6469258151 / 6469272336, as the review required ([finding] the skip-changeset label suppresses the DELIBERATE-CORRECTION refusal whose own text says 「no label and no diff shape makes that safe」 — declared contract against enforced behaviour #18375 FOREIGN_CORRECTION_REMEDY).
  6. Landing: Tier H. This record is pinned before ready. The PR gets needs-user-decision, is readied (which requests the GOVERNED_APPROVERS), and the seat arms auto-merge only after a governed approval given after this record. The seat then closes refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 as superseded (or reports if refused).

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit c59b1bf Oct 28, 2026
63 of 66 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-26wk5s branch October 28, 2026 14:43
os-justin pushed a commit that referenced this pull request Oct 28, 2026
#27042 retired plugin-ai and its README, which carried 3 decidable and 1
site-absolute href; with the extension README this card removes, the floors
read 126 and 39 on the merged tree.

Claude-Session: https://claude.ai/code/session_01QSeKYm29SiQaonK2q8F7CS
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation needs-user-decision size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants