Skip to content

fix(plugin-auth,plugin-webhooks): retire a dead degrade branch and an implicit transitive dependency (#4187) - #4211

Merged
os-zhuang merged 1 commit into
mainfrom
claude/plugin-ordering-convention-t9ylrz
Jul 30, 2026
Merged

fix(plugin-auth,plugin-webhooks): retire a dead degrade branch and an implicit transitive dependency (#4187)#4211
os-zhuang merged 1 commit into
mainfrom
claude/plugin-ordering-convention-t9ylrz

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

收尾 #4187 的第 1–3 项(第 4 项见文末)。两处具体缺陷 + 一条本可以预防它们的编写规则。

1. plugin-auth 宣称了一个它并不具备的降级模式

init() 里原本是:

const dataEngine = ctx.getService<any>('data');
if (!dataEngine) {
  ctx.logger.warn('No data engine service found - auth will use in-memory storage');
}

这条分支永远不会执行,两重原因叠加:

  • getService 在服务未注册时是抛错,不会返回 undefined
  • 该插件硬依赖 com.objectstack.engine.objectql,而后者无条件注册 data。没有引擎的内核会更早死在 Dependency 'com.objectstack.engine.objectql' not found

也就是说它宣传的 "in-memory storage" 是一个组装方式本身就禁止的模式。删掉分支,并把真实契约声明出来:requiresServices: ['data', 'manifest']——顺带把原来那句行尾注释 // manifest service required 换成了机器可校验的同一主张。

AuthManager 内部的 dataEngine? 判空保留不动:它可以脱离本插件独立使用,那些判空在别的调用场景下是有意义的。

2. plugin-webhook-outbox 只被传递依赖保护着

它在 init() 里无兜底地取 manifest,却只声明 dependencies: ['com.objectstack.service.messaging']——靠 messaging 恰好依赖 ObjectQL 才成立。这条链哪天断了(messaging 不再依赖引擎),故障会以"另一个插件 init 崩溃"的形式出现,排查方向完全错位。改为直接声明 requiresServices: ['manifest']

两处改动都不改变任何现有组装的排序或启动结果——它们本来就排对了。改变的是组装出错时的报错内容,以及这份保证从"继承来的"变成"被校验的"。

3. 把规则写进文档

content/docs/plugins/anatomy.mdx:补上 ADR-0116 的三个字段,以及"在 init() 里同步取服务该怎么声明"的二选一表格(硬 dependencies vs optionalDependencies + requiresServices),并明确写进促成本 PR 两个修复的两个坑:

  • 别依赖传递 provider;
  • 别在裸 getService 后面写 if (!svc) { 降级 }——那是死代码,宣传了一个不存在的模式。

顺手把 api-registry-example.ts7 个插件全部补上声明。原先它们全靠 kernel.use() 顺序工作,而示例正是模式被复制的源头;只改其中 2 个会让示例自相矛盾,所以要么都改要么都不改。

4. D4(服务声明自动推导排序)本次仍不做

证据继续支持"不做":provider 侧刚补齐(#4185),消费方侧 12 个一致地选择了硬依赖,说明"硬依赖排序 + 服务声明校验/诊断"这套两级机制已经覆盖了真实用法。等出现第二、第三个像 AppPlugin 那样的软依赖消费方再回头看。#4187 保持 open 记录这一项。

验证

  • pnpm build 71/71 通过。
  • 全仓 pnpm test 运行中(退出码写入独立文件,不走管道——本次会话早先在这上面误报过一次)。

🤖 Generated with Claude Code

https://claude.ai/code/session_014DQuJBNpwStpJvo3owBw2B


Generated by Claude Code

… implicit transitive dependency (#4187)

Two concrete findings from the ADR-0116 consumer-side audit, plus the
authoring rule that would have prevented both.

plugin-auth claimed a fallback it did not have: init() ran
`const dataEngine = ctx.getService('data'); if (!dataEngine) { warn(...
"auth will use in-memory storage") }`. That branch could never execute —
getService THROWS for an unregistered service rather than returning
undefined, and this plugin declares a hard dependency on ObjectQL (which
registers `data` unconditionally), so a kernel without the engine fails
earlier still with "Dependency ... not found". The branch is removed and
the real contract declared as requiresServices: ['data', 'manifest'],
which also replaces a trailing `// manifest service required` comment
with the machine-checked form of the same claim. AuthManager keeps its
own optional dataEngine guards — it is usable outside the plugin.

plugin-webhook-outbox was protected only transitively: it resolves
`manifest` in init() with no fallback while depending on messaging,
which in turn depends on ObjectQL, the actual provider. That would have
broken silently the day messaging stopped depending on the engine, and
surfaced as a crash inside an unrelated plugin's init. It now declares
requiresServices: ['manifest'] directly.

Neither change alters ordering or boot outcomes on any current
composition — both plugins were already ordered correctly. What changes
is what a broken composition says, and that the guarantees are checked
rather than inherited.

Docs: anatomy.mdx gains the three ADR-0116 fields and the decision rule
for resolving a service inside init(), including the two traps behind
these fixes. The api-registry example declares the contract on all seven
of its plugins instead of relying on kernel.use() order.

Refs #4187

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014DQuJBNpwStpJvo3owBw2B
@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 3:34pm

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 3 package(s): @objectstack/core, @objectstack/plugin-auth, @objectstack/plugin-webhooks.

27 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx (via @objectstack/core)
  • content/docs/ai/knowledge-rag.mdx (via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx (via @objectstack/core)
  • content/docs/automation/webhooks.mdx (via @objectstack/core, packages/plugins/plugin-webhooks)
  • content/docs/concepts/north-star.mdx (via packages/core)
  • content/docs/deployment/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/core)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/core)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/core)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/core, @objectstack/plugin-auth)
  • content/docs/kernel/services.mdx (via @objectstack/core)
  • content/docs/permissions/authentication.mdx (via @objectstack/core, @objectstack/plugin-auth)
  • content/docs/permissions/authorization.mdx (via packages/core)
  • content/docs/permissions/sso.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/anatomy.mdx (via @objectstack/core)
  • content/docs/plugins/development.mdx (via @objectstack/core)
  • content/docs/plugins/index.mdx (via @objectstack/core, @objectstack/plugin-auth)
  • content/docs/plugins/packages.mdx (via @objectstack/core, @objectstack/plugin-auth, @objectstack/plugin-webhooks)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/core)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/core)
  • content/docs/releases/implementation-status.mdx (via @objectstack/core, @objectstack/plugin-auth, @objectstack/plugin-webhooks)
  • content/docs/releases/v12.mdx (via @objectstack/core)
  • content/docs/releases/v15.mdx (via @objectstack/core)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 30, 2026 15:48
@os-zhuang
os-zhuang merged commit bb1ce2e into main Jul 30, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/plugin-ordering-convention-t9ylrz branch July 30, 2026 15:49
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

Development

Successfully merging this pull request may close these issues.

2 participants