Skip to content

Commit c118524

Browse files
docs(adr-0026): spell the UI plugin package type ui, note the original ui-plugin (#19769)
Part of #16140 Clause-②: no This PR executes ruling 5563454219 on `docs/adr/0026-client-ui-plugin-distribution.md` and nothing else. The ruling came from the director seat in decision batch #61 (option A); the maintainer's reply, verbatim, was 「同意」. ## What changed - Section 3.1 manifest example (`:80`): `"type": "ui-plugin"` is now `"type": "ui"`. - Section 3.7 prose (`:170` on base, `:176` after the note): `type: ui-plugin` is now `type: ui`. - One note directly under the example records that `ui-plugin` was this proposal's original spelling and that the closed set (`CORE_PLUGIN_TYPES`) adopted `ui`. The ADR's argument, its `Proposed` status line and every other line are unchanged. The diff is 1 file, +8 / -2. Two things are deliberately untouched: - the pins `packages/core/src/plugin-type-closed-set.test.ts` and `packages/rest/src/plugin-type-closed-set.pin.test.ts`; - #15638, the runtime tolerance arm in `plugin-hono-server`. It remains open and is not addressed here. ## Premise check (base `ed4b655e5b`) - ADR-0026 line 3 reads `**Status**: Proposed`. - `ui-plugin` occurs exactly twice in the file: at `:80`, inside the jsonc example, and at `:170`, in prose. - `CORE_PLUGIN_TYPES` (`packages/spec/src/kernel/plugin.zod.ts:90`) is `ui, driver, server, app, theme, agent, objectql`. There is no `ui-plugin`. Two of the card's readings have drifted since it was filed. Neither affects the ruling: - The `ManifestSchema.type` enum is now at `manifest.zod.ts:430`, and `ManifestSchema` is now a `strictObject`, which refuses unknown keys. - `PluginSchema.safeParse({type:'ui'})` is no longer `success=true`: `type: 'ui'` now requires `staticPath` and `slug` (`PLUGIN_UI_REQUIRED_KEY_MISSING`). The reading on the `type` key itself still holds on both schemas. ## Proof: the example against the built schema The instrument is a throwaway probe, not committed. It takes the section 3.1 jsonc block from the committed file at each revision (`git show REV:docs/adr/...`) and strips the `//` comments that sit outside strings. It then parses the result with `ManifestSchema` and `PluginSchema` from a fresh `pnpm --filter @objectstack/spec build` of this branch, loaded through the package's `exports` map (`packages/spec/dist/kernel/index.js`, not `src/`). "Before" is base `ed4b655e5b` and "after" is `e968910ad5`. The `type` key, on both schemas. The before leg is the firing control: the same instrument refuses it. ```text before ManifestSchema {type:"ui-plugin"} -> ["type"] invalid_value PluginSchema {type:"ui-plugin"} -> ["type"] invalid_value after ManifestSchema {type:"ui"} -> no issue at ["type"] PluginSchema {type:"ui"} -> no issue at ["type"] ``` The example's keys whose values the current schema already accepts (`id`, `version`, `type`, `integrity`), parsed with `ManifestSchema.pick` of those keys: ```text before success=false | ["type"] invalid_value after success=true ``` The whole example, as pasted, against `ManifestSchema`: ```text before success=false, 6 issues: ["type"] invalid_value, ["name"] invalid_type, ["permissions"] invalid_union, ["engines"] unrecognized_keys [objectui, react], ["runtime"] invalid_value, [] unrecognized_keys [ui] after success=false, 5 issues: the same list without ["type"] removed by the edit: ["type"] invalid_value introduced by the edit: none ``` ## Acceptance notes - **This edit alone does not meet the ruling's general rule.** The rule says any example under `docs/adr/**` that an author could paste must validate against the current schema. After this edit, `ManifestSchema` still refuses the section 3.1 example on five counts, and none of them is `type`: - `runtime: "ui"`: `PluginRuntimeSchema` accepts only `node`, `sandbox` or `worker`. The example itself annotates this value "new tier". - `engines.objectui` and `engines.react`: `PluginEnginesSchema` declares only `platform` and `protocol`. - The top-level `ui` block is not a `ManifestSchema` key. - `permissions.data` and `permissions.navigation`: the structured branch declares only `services`, `hooks`, `network` and `fs`. - `name` is required by `ManifestSchema`, and the example never had it. The first four are schema extensions the proposal makes and that were never adopted. Correcting them would change what the ADR proposes, which the ruling does not authorise, so this PR leaves them alone and reports them to the seat as an open question. - `PluginSchema` is not the example's schema, because the example is an `.osplugin` package manifest. `PluginSchema` is a non-strict `z.object` and strips the manifest's keys. On the after leg it trades the `type` refusal for `PLUGIN_UI_REQUIRED_KEY_MISSING` on `staticPath` and `slug`, which are runtime-plugin keys that a package manifest does not carry. This is recorded for completeness and is not a defect in the example. - The same spelling survives in prose at `docs/design/plugin-distribution.md:127` and `:277` (`type: ui-plugin`). That file is outside this card's one-file write surface, so it is reported to the seat and not changed here. ## Changeset There is no changeset. `skip-changeset` is the right label, as the ruling says. Measured: - 70 non-private `package.json` manifests scanned; 0 of their `files[]` entries reach `docs/adr/`. - A string unique to this ADR's example (`com.acme.signature-field`) has 0 hits across the built `@objectstack/spec` `dist/` and `json-schema/`. The positive control, `PLUGIN_UI_REQUIRED_KEY_MISSING`, has 16. This PR does not write the label. ## Gates (at `e968910ad5`) `node scripts/pm/dispatch-gates.mjs --commands` derived 19 commands for this change set. All 19 were run, and each exited 0. `check:doc-formula-expressions` first stopped at `PREREQUISITE NOT MET` (exit 3, nothing measured); after building `@objectstack/formula` and `@objectstack/lint` it exited 0. The `dispatch-gates --ran` reconciliation reads: "19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED (a DERIVED zero — all 19 recorded an exit code and none of them is 3)". Selected verdict lines: - `check-adr-links`: 690 relative link destination(s) under docs/adr/ resolve - `check-adr-symbol-anchors`: 2122 anchors across 140 records resolve - `check-adr-anchors`: OK - `check:doc-authoring`: no growth - `check-nul-bytes`: OK, no raw ASCII control bytes No package source is touched, so no package build, test or typecheck is owed. The `@objectstack/spec` build served the proof only. Repo-wide scans such as `pnpm lint` run in CI. ## Governed surface `docs/adr/**` is tier H on the governed-surface register. This PR stays **draft**. It lands only by a human merge through `GOVERNED_APPROVERS`. ## 维护者速读(草稿) **改了什么**:ADR-0026 §3.1 manifest 示例和 §3.7 正文里的包类型 `ui-plugin` 改成了 `ui`;示例下方加了一条注记,说明 `ui-plugin` 是本提案最初的拼写,闭集 `CORE_PLUGIN_TYPES` 后来采用的是 `ui`。只改这一个文件,+8/-2。 **为什么改**:执行第 61 批裁决的选项 A(您回复「同意」)。原来作者照抄示例时,`type: "ui-plugin"` 会同时被 `ManifestSchema` 和 `PluginSchema` 拒收。 **风险与代价(含回滚)**:纯文档,不发布任何包,运行时零影响;回滚就是 revert 本 PR。有一点需要您知道:改完后 `type` 已经能通过,但整个示例仍会被 `ManifestSchema` 拒收 5 处,即 `runtime: "ui"`、`engines.objectui/react`、顶层 `ui` 块、`permissions.data/navigation`,以及缺少必填的 `name`。前四处是提案自己提出、至今未被采纳的 schema 扩展。因此光靠本 PR 还满足不了裁决附带的通则「可照抄的示例必须能通过当前 schema」,这一点已作为待决问题交给席位。 **席位意见**: **你要做的**:审阅后合并(这是治理面,需要您本人或 `GOVERNED_APPROVERS` 批准)。另外请就上面剩下的 5 处拒收定一个方向。 --- _Generated by [Claude Code](https://claude.ai/code/session_013RDBh5DqXd2xnLwvHLgLFr)_ --- _Generated by [Claude Code](https://claude.ai/code)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 492598e commit c118524

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

‎docs/adr/0026-client-ui-plugin-distribution.md‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ A UI plugin is an `.osplugin` with:
7777
{
7878
"id": "com.acme.signature-field",
7979
"version": "1.0.0",
80-
"type": "ui-plugin",
80+
"type": "ui",
8181
"runtime": "ui", // new tier (ADR-0025 §3.6)
8282
"engines": { "objectui": ">=1.0 <2", "react": "^19" }, // protocol + shared singletons
8383
"ui": {
@@ -98,6 +98,12 @@ A UI plugin is an `.osplugin` with:
9898
}
9999
```
100100

101+
> **Note (2026-09-07, #16140).** This proposal originally spelled the package
102+
> type `ui-plugin`. The closed set of plugin types (`CORE_PLUGIN_TYPES`,
103+
> `packages/spec/src/kernel/plugin.zod.ts`) adopted `ui`, and both
104+
> `ManifestSchema` and `PluginSchema` refuse `ui-plugin`; the example above and
105+
> §3.7 use `ui`.
106+
101107
`extends` reuses the existing `capabilities.extensionPoints`/`extensions` seam;
102108
`ui.shared` lists singletons the host injects (never bundled — same externalize
103109
rule as ADR-0025 §3.3, applied to browser deps).
@@ -167,7 +173,7 @@ client analog of ADR-0025 §3.8 protocol-first gating.
167173

168174
### 3.7 Audience & relation to ADR-0019
169175

170-
As in ADR-0025 §3.11, a UI plugin (`type: ui-plugin`) is an **internal
176+
As in ADR-0025 §3.11, a UI plugin (`type: ui`) is an **internal
171177
contribution**, not a consumer-installable unit (ADR-0019 D2:
172178
`isConsumerInstallable` = `type: app` only). It reaches a tenant by the same two
173179
routes:

0 commit comments

Comments
 (0)