Skip to content

docs(adr): ADR-0115 — the stub table is retired; plugin-dev assembles, empty slots stay empty (#4093) - #4103

Merged
os-zhuang merged 3 commits into
mainfrom
claude/plugin-dev-stub-slots-eval-hqjox1
Jul 30, 2026
Merged

docs(adr): ADR-0115 — the stub table is retired; plugin-dev assembles, empty slots stay empty (#4093)#4103
os-zhuang merged 3 commits into
mainfrom
claude/plugin-dev-stub-slots-eval-hqjox1

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #4093.

#4093 要求的是评估,不是删除 —— 本 PR 交付评估本身:ADR-0115,裁决为「stub 填满槽位」这个早期设计整体作废,plugin-dev 收敛为纯装配插件。空槽位在 dev 和生产里含义相同,这条从 #3891 一路退役到 #4086 的规则不再逐个槽位适用,而是升为设计层结论。

裁决依据(issue 的四条证据全部核实,另加一条 issue 没有的)

Issue 的证据 1–4 逐条对着源码核实无误(原设计理由被 #4086 的"一次清空 4 个槽位全绿"直接反证;三个安全 stub 撞 D12 红线且伪造的是 security-service.ts 明说"deliberately NOT part of this contract"的别家内部件;metadata 双份实现有 core CHANGELOG 里"同一个 bug 修两处"的收据;包已发布、无护栏、仓库内无使用者、文档描述错误)。

评估新增的证据 5 —— C 档比 issue 以为的小得多,且不需要"先补 InMemory 策略"

  • realtime:真实包已经带着 InMemory 策略(service-realtime/src/in-memory-realtime-adapter.ts,且是该插件注册 realtime 槽位的默认实现)—— issue 想让人先去建的迁移路径已经存在;
  • file-storageservice-storage 是真实包(local + S3 适配器),local 适配器就是 dev 路径;
  • search / workflow / ui整个仓库没有任何代码解析这三个槽位getService('search'|'workflow'|'ui') 零调用点;dispatcher 无对应域;REST 的 /api/v1/search 是数据面搜索,不碰 search 服务)—— 这三个 stub 服务于不存在的调用方,退役不可能造成任何回归。

三个待定问题的答案(= ADR 的 D4/D5/D6)

  1. breaking 面 → 17.x rc 窗口内直接切,changeset 带每槽位 FROM→TO。不留 deprecation 窗口:fix(core,plugin-dev,runtime): every in-memory fallback and dev stub self-describes honestly (#4058 step 1) #4082/fix(runtime,metadata-protocol): every dispatcher domain gates on handlerReady, not slot occupancy (#4058 step 2) #4086 的诚实自述本身就是 deprecation 通知,而让 allow-all 安全假实现"客气地"多活一个版本正是 D12 红线禁止的事。
  2. C 档顺序 → 无需先补策略再退役:该存在的 InMemory 策略已在真实包里(realtime/storage),其余(search/workflow)没有需求方;未来真实服务落地时自带 InMemory 策略(analytics 先例)。
  3. 环境护栏 → 要,但与 A 档同 PR 落地而非提前单走:删除本身消掉安全语义风险,护栏(NODE_ENV === 'production' 断言 + OS_ALLOW_DEV_PLUGIN_IN_PRODUCTION 逃逸阀,PD [WIP] Create a new release version #9 形状)盖住删除盖不住的部分(默认 dev auth secret + seed admin)。

执行序(ADR Execution 节)

  1. fix(runtime,metadata-protocol): every dispatcher domain gates on handlerReady, not slot occupancy (#4058 step 2) #4086 先合(在途,dispatcher 其余服务域仍只判槽位占用、不读 handlerReady —— #4000 在 analytics 一域落地后剩下的类推面 #4058 step 2)—— 本评估以它的分类为基线,也避免两个 open PR 同时改 dev-plugin.ts
  2. A 档 + 护栏(一个 PR);
  3. B 档并 core 的内存 fallback 带 _fallback: true 而非 __serviceInfo,readServiceSelfInfo 不识别 —— AppPlugin 注册的 i18n fallback 在 discovery 里报 available #4089(一个 PR,core fallback 家族成为唯一份);
  4. C 档(一个 PR,指路 service-storage / service-realtime);
  5. 文档收敛(packages.mdx / README / class doc)。

终态可机械检验:DEV_STUB_FACTORIES / DEV_STUB_SELF_INFO / SHAPELESS_STUB_SELF_INFO / NO_DEV_STUB_SERVICES 与填充循环从 dev-plugin.ts 消失。

验证

  • docs-only(一个新 ADR 文件),不触发任何生成物 gate;
  • ADR 内所有文件路径 / 行号 / 引文逐一对照当前 main 源码核实(含 security-service.ts 的契约措辞、core CHANGELOG 收据、resolve-execution-context.ts 的真实身份路径、realtime-service-plugin.ts:59 的默认适配器、零调用点的 grep)。

🤖 Generated with Claude Code

https://claude.ai/code/session_01BEM82RNKyyyTNPYHK1VJJS


Generated by Claude Code

…, empty slots stay empty (#4093)

The evaluation #4093 asked for, recorded as a decision. The founding
premise of plugin-dev's fill-every-slot design (downstream needs correct
return types instead of undefined) is refuted by production semantics —
every slot is optional there, and four one-at-a-time retirements
(#4000, #4058) already proved empty slots regress nothing. Verdict:
retire the design, not more members of it; plugin-dev converges to a
pure assembly plugin.

Disposition is tiered: fabricators (data/auth/security.*/ui) go first
with a production guard; core's fallback family becomes the one copy
(with #4089); the working in-memory tier retires without a rebuild
phase — service-realtime already ships the InMemory adapter,
service-storage is real, and the search/workflow slots have zero
consumers in the repo. Direct cut in the 17.x rc window with FROM→TO
changesets; sequenced behind the in-flight #4086.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEM82RNKyyyTNPYHK1VJJS
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 30, 2026 10:23am

Request Review

The changeset gate counts changesets added by the PR; an
empty-frontmatter file is its sanctioned 'this PR releases nothing'
declaration (same pattern as adr-0044-revise-service-owned-note).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEM82RNKyyyTNPYHK1VJJS
… lands as assembly auto-wire

Maintainer review confirmed D5's direct cut and collapsed the tier
work: PR-1 = Tier A + Tier C + production guard + optional
service-storage/service-realtime child plugins (the 3b i18n
auto-detect precedent — zero-config kept by real implementations);
PR-2 = Tier B + #4089 + docs convergence. Tracked in #4104.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEM82RNKyyyTNPYHK1VJJS
@os-zhuang
os-zhuang marked this pull request as ready for review July 30, 2026 10:30
@os-zhuang
os-zhuang merged commit 8b03102 into main Jul 30, 2026
15 checks passed
@os-zhuang
os-zhuang deleted the claude/plugin-dev-stub-slots-eval-hqjox1 branch July 30, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

2 participants