Skip to content

Commit d51bed2

Browse files
os-zhuangclaude
andauthored
refactor(spec)!: retire the plugin-runtime family — the "Dynamic Loading" vocabulary no runtime implemented (#4834, ADR-0049) (#4878)
ADR-0049 enforce-or-remove, maintainer-ruled REMOVE. `DynamicLoadRequestSchema`, `DynamicUnloadRequestSchema`, `DynamicPluginResultSchema`, `PluginSourceSchema` and `DynamicPluginOperationSchema` (+ seven type aliases) declared runtime load / unload / reload of plugins without a kernel restart — sources, integrity hashes, sandboxing, drain strategies, dependent-cascade policy. None of those operations exists. Bare-name scan of objectstack, cloud (5df2c69) and objectui (785b8a5): zero references outside this package's declaration, its unit tests and the generated artifacts, each empty result control-verified against a known-present neighbour. The whole module is deleted. #3896 removed this module's discovery/sandbox config island and left these five in place explicitly ("operation contracts, not security promises; the enforce-or-remove call on them is a design decision rather than a correction") — a suspension that lived only in a changeset paragraph with no issue carrying it. #4834 is that decision. Route: whole-def removal (#4650 route 3). No `retiredKey()` tombstones — nothing parses these schemas, so a prescription could never be received; the same disposition this module set in #3896. The `json-schema.manifest.json` ratchet (#2978) demanded the five def keys be deleted deliberately, and gen:schema then reported all 23 authorable-surface deletions as carrying their own proof ("def no longer emitted by this build"). This subsumes the kernel half of #4657: `DynamicLoadRequest.activationEvents`'s `retiredKey()` tombstone goes with the shape that carried it, which is strictly stronger than the tombstone ("this request shape does not exist" > "this one key does not exist"). The studio half (`StudioPluginManifest.activationEvents`) is untouched and still enforced. The #4657 D3 entry is corrected rather than deleted — its studio half is live and its history must keep replaying. - ADR-0087 D3 semantic migration `plugin-runtime-family-retired` (no `sys_metadata` source exists for a D2 rewrite: these are root request/result payload shapes, embedded in no parent schema) - compiler-API export pin with three anti-vacuity guards, `holdersOf(name)` exactly `[]` across all 16 entries — sabotage-verified - PLUGIN_STANDARDS.md §5.3 + capability table now say "Not built", not ✅ - baselines regenerated from rebuilt source; changeset carries the merged two-layer migration narrative Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 164f344 commit d51bed2

17 files changed

Lines changed: 439 additions & 691 deletions
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
"@objectstack/spec": major
3+
---
4+
5+
refactor(spec)!: remove the `plugin-runtime.zod` family — the "Dynamic Loading" vocabulary no runtime ever implemented (#4834, ADR-0049)
6+
7+
`DynamicLoadRequestSchema`, `DynamicUnloadRequestSchema`,
8+
`DynamicPluginResultSchema`, `PluginSourceSchema` and
9+
`DynamicPluginOperationSchema` — with every type alias — are **removed from
10+
`@objectstack/spec` and `@objectstack/spec/kernel`**. The module they lived in
11+
is deleted.
12+
13+
Together they declared the platform's "Dynamic Loading" capability: runtime
14+
load / unload / reload of plugins **without restarting the kernel**, resolved
15+
from `npm` / `local` / `url` / `registry` / `git` sources, with Subresource
16+
Integrity hashes, per-plugin sandboxing, `graceful` / `forceful` / `drain`
17+
unload strategies and `cascade` / `warn` / `block` dependent policy. **None of
18+
those operations exists.** A bare-name scan of objectstack, cloud and objectui
19+
(at the commits above) found zero references outside this package's own
20+
declaration, its unit tests and the generated artifacts: no runtime ever
21+
received a `DynamicLoadRequest`, performed a load or an unload, or produced a
22+
`DynamicPluginResult`. Plugins are composed at boot — `defineStack` registers
23+
them and the kernel runs `init``start` — and the set is fixed until the
24+
process restarts.
25+
26+
This closes a suspension that has been open, and undocumented outside one
27+
paragraph, since #3896. That change removed this module's discovery/sandbox
28+
config island and wrote down that "the remainder … also has no runtime consumer
29+
today; it is left in place because those are operation contracts, not security
30+
promises, and the enforce-or-remove call on them is a design decision rather
31+
than a correction." That decision lived only in a changeset, carried by no
32+
issue. #4834 is the decision, and the answer is **remove**: `experimental` was
33+
weighed and rejected because it is `.describe()` prose that cannot stop an
34+
`import` — the weakest of ADR-0049's three channels — and because a
35+
request/result vocabulary published into the IDE bundle is precisely what an AI
36+
author (ADR-0033) reads as proof the platform hot-loads plugins, then builds a
37+
request that parses clean and is received by nobody (#3950).
38+
39+
Migration (FROM → TO):
40+
41+
- `import { DynamicLoadRequestSchema, DynamicUnloadRequestSchema,
42+
DynamicPluginResultSchema, PluginSourceSchema, DynamicPluginOperationSchema }
43+
from '@objectstack/spec/kernel'` (or from `@objectstack/spec`) →
44+
**no replacement export.** Every one is `TS2305: Module … has no exported
45+
member` after upgrade, on every public entry. Same for the type aliases
46+
`DynamicLoadRequest`, `DynamicUnloadRequest`, `DynamicPluginResult`,
47+
`PluginSource`, `DynamicPluginOperation`, `DynamicLoadRequestInput`,
48+
`DynamicUnloadRequestInput`.
49+
- A **`DynamicLoadRequest` / `DynamicUnloadRequest` value** you built → delete
50+
it, along with whatever was going to send it. There was never a recipient;
51+
the code that constructed one was already a no-op with extra steps. To get a
52+
plugin into a running system, put it in the stack (`defineStack`) and restart.
53+
- A **`DynamicPluginResult`** you typed a handler against → delete the handler.
54+
Nothing ever produced one.
55+
- **`activationEvents` inside a `DynamicLoadRequest`** — the key #4657
56+
tombstoned one release-candidate earlier — now has a *stronger* answer than
57+
that tombstone gave. #4657 told you: delete this key from your
58+
`DynamicLoadRequest`. **The correct instruction is now: delete the entire
59+
`DynamicLoadRequest`.** The shape that carried the key is gone, so its
60+
`retiredKey()` prescription is gone with it — legitimately, because "this
61+
request shape does not exist" is strictly stronger than "this one key of it
62+
does not exist". If you are upgrading from v16 and wrote `activationEvents`
63+
in *either* form (v16 strings `['onMetadataType:flow']`, or the v17-rc
64+
structured `[{ type, pattern }]` from #4653), you do not need to migrate the
65+
key at all — the value it sat in has no shape and no recipient.
66+
**The studio half of #4657 is unaffected**: `StudioPluginManifest`
67+
(`defineStudioPlugin`) is a live authoring surface and still rejects
68+
`activationEvents` with its own prescription. Delete the key there.
69+
- Runtime plugin loading is a **new capability**, not a restoration: if it is
70+
ever built it returns via the enforce route of ADR-0049 through a new ADR —
71+
loader first, vocabulary second. The shapes it needs are unlikely to be these
72+
ones, which is itself a reason not to keep them as a design constraint on
73+
work that has not started.
74+
75+
Self-check (#4535 §5):
76+
77+
1. **TS2305 / TS2339 — what exactly breaks?** TS2305 on twelve names, at two
78+
entry points (`@objectstack/spec` root and `@objectstack/spec/kernel`) — the
79+
five `*Schema` consts and the seven type aliases listed above. No TS2339:
80+
nothing removed was a *property* of a surviving shape, because the removed
81+
defs were embedded in no parent schema. `PluginSource` was reachable only as
82+
`DynamicLoadRequest.source` and `DynamicPluginOperation` only as
83+
`DynamicPluginResult.operation`, both of which go in the same change.
84+
2. **Metadata migration — is there any?** No, and none is possible. All five
85+
are root request/result payload shapes: no metadata-type root reaches them
86+
(`gen:schema`'s reachability BFS says so — see the gate output below), no
87+
`sys_metadata` row can carry one, and no `.stack.ts` / `objectstack.config.ts`
88+
authoring surface embeds one. There is therefore no source for an ADR-0087
89+
**D2** conversion to rewrite, and `os migrate meta` would have nothing to
90+
match. Registered instead as an ADR-0087 **D3** semantic migration,
91+
`plugin-runtime-family-retired`, which is where a removal with no rewritable
92+
source belongs — the same disposition as #4616, #4767 and #4783. The
93+
pre-existing D3 entry `plugin-activation-events-retired` (#4657) is
94+
**corrected, not deleted**: its studio half is still live and its historical
95+
record must keep replaying, so its kernel half now records this supersession
96+
rather than continuing to promise a tombstone that no longer exists.
97+
3. **Shape change — what kind?** Pure removal of five whole defs; zero
98+
additions, zero narrowings, zero renames. Runtime behaviour is unchanged in
99+
the strongest sense available: not "equivalent", but *identical*, because no
100+
code path anywhere consumed any of it.
101+
102+
The retirement kit: whole-def removal (#4650 route 3 — the defs stop being
103+
emitted, adjudicated by the `json-schema.manifest.json` ratchet (#2978) and
104+
`check:api-surface`, not by the per-key tombstone ratchet, which reported all 23
105+
`authorable-surface.json` deletions as carrying their own proof); no
106+
`retiredKey()` tombstones, deliberately — nothing parses these schemas any more,
107+
and a prescription nobody can receive is noise (the precedent this same module
108+
set in #3896); ADR-0087 D3 semantic migration + the corrected #4657 entry;
109+
baselines (`json-schema.manifest.json` −5 defs, `authorable-surface.json` −23
110+
lines, `api-surface.json` −12 names, `spec-changes.json`,
111+
`docs/protocol-upgrade-guide.md`, `content/docs/references/kernel/`) regenerated
112+
from the rebuilt source rather than hand-edited; `PLUGIN_STANDARDS.md` §5.3 and
113+
its capability table now say **Not built** instead of ✅; compiler-API export pin
114+
(`plugin-runtime-retirement.test.ts` — zero holders for all twelve names across
115+
every entry in the `package.json` exports map, with three anti-vacuity guards),
116+
sabotage-verified.

content/docs/references/kernel/index.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ This section contains all protocol schemas for the kernel layer of ObjectStack.
3030
<Card href="/docs/references/kernel/plugin-lifecycle-advanced" title="Plugin Lifecycle Advanced" description="Source: packages/spec/src/kernel/plugin-lifecycle-advanced.zod.ts" />
3131
<Card href="/docs/references/kernel/plugin-loading" title="Plugin Loading" description="Source: packages/spec/src/kernel/plugin-loading.zod.ts" />
3232
<Card href="/docs/references/kernel/plugin-registry" title="Plugin Registry" description="Source: packages/spec/src/kernel/plugin-registry.zod.ts" />
33-
<Card href="/docs/references/kernel/plugin-runtime" title="Plugin Runtime" description="Source: packages/spec/src/kernel/plugin-runtime.zod.ts" />
3433
<Card href="/docs/references/kernel/plugin-security" title="Plugin Security" description="Source: packages/spec/src/kernel/plugin-security.zod.ts" />
3534
<Card href="/docs/references/kernel/plugin-security-advanced" title="Plugin Security Advanced" description="Source: packages/spec/src/kernel/plugin-security-advanced.zod.ts" />
3635
<Card href="/docs/references/kernel/plugin-structure" title="Plugin Structure" description="Source: packages/spec/src/kernel/plugin-structure.zod.ts" />

content/docs/references/kernel/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"plugin-lifecycle-advanced",
77
"plugin-loading",
88
"plugin-registry",
9-
"plugin-runtime",
109
"plugin-structure",
1110
"plugin-validator",
1211
"---Plugin Security & Dependencies---",

content/docs/references/kernel/plugin-runtime.mdx

Lines changed: 0 additions & 131 deletions
This file was deleted.

0 commit comments

Comments
 (0)