feat(kernel): kernel:bootstrapped anchor + fix everyone auto-bind ordering (#2926 follow-ups)#2989
Merged
Merged
Conversation
kernel:ready handlers run sequentially in plugin-registration order, so a handler that consumes data produced by a later-starting plugin (security bootstrap seeds sys_position; the app plugin's seed loader inserts records) races the very rows it needs. Add kernel:bootstrapped — fired after every kernel:ready handler has settled but before kernel:listening (HTTP socket open) — as the correct anchor for reconcile/backfill work. Both ObjectKernel and LiteKernel trigger it; ordering is locked by tests in kernel.test.ts and lite-kernel.test.ts. The sharing-rule boot backfill moves from kernel:listening to kernel:bootstrapped (semantics-only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017bJWtKmZ2mFpRFAmmmoeqe
…is seeded The ADR-0090 D5 baseline auto-bind ran earlier in runBootstrap than bootstrapBuiltinRoles, which creates the everyone position — so the everyone lookup returned nothing and the app's isDefault set (resolved as fallbackPermissionSet) was never bound. A fresh deploy booted with everyone empty (personas silently degraded) plus a redundant sys_audience_binding_suggestion for the same set. Move the auto-bind after bootstrapBuiltinRoles and before syncAudienceBindingSuggestions so the documented app-level auto-bind actually happens and the suggestion sync skips the already-bound set. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017bJWtKmZ2mFpRFAmmmoeqe
…edundant everyone binding The security plugin now auto-binds the app's isDefault set (showcase_member_default) to everyone at boot, so the app glue no longer needs to. Keep only the persona → set bindings the framework cannot infer, and move them from kernel:listening to the kernel:bootstrapped anchor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017bJWtKmZ2mFpRFAmmmoeqe
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 4 package(s): 109 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
两个框架层 follow-up,均源自 #2926 E2E 时暴露的
kernel:ready生命周期时序问题(#2983 里用kernel:listening临时兜住,这里做正解)。G1 — 新增
kernel:bootstrapped生命周期锚点kernel:ready的处理器按插件注册顺序串行 await(kernel.ts)。早启动插件注册的 hook 会在后启动插件的 bootstrap/种子加载之前跑——消费这些数据的 reconcile/backfill 逻辑因此与它要用的行竞态。目前只能借用kernel:listening(HTTP 开监听)当"数据就绪"锚点,语义不对。kernel:bootstrapped:在所有kernel:ready处理器 settle 之后、kernel:listening(开 socket)之前触发。这是"所有 bootstrap + 种子数据就绪"的正确锚点。ObjectKernel与LiteKernel都触发;顺序由kernel.test.ts/lite-kernel.test.ts的锁定测试保证(ready → bootstrapped → listening)。kernel:listening)。kernel:listening→kernel:bootstrapped(语义修正,行为不变)。改动:
packages/spec/src/contracts/plugin-lifecycle-events.ts、packages/spec/src/kernel/plugin-lifecycle-events.zod.ts、packages/core/src/kernel.ts、packages/core/src/lite-kernel.ts(+ 各自测试)、packages/plugins/plugin-sharing/src/sharing-plugin.ts、docs。G2 — 修复 everyone baseline 自动绑定的时序 bug
ADR-0090 D5 说 app 的
isDefault集在 boot 时自动绑到everyone。但代码从来没绑上:runBootstrap里 auto-bind 段跑在bootstrapBuiltinRoles(创建everyone锚点)之前——everyone查询返回空,绑定静默失败,fresh 部署的everyone空壳、personas 降级,还多出一条冗余sys_audience_binding_suggestion。段里的注释甚至写反了顺序。bootstrapBuiltinRoles之后、syncAudienceBindingSuggestions之前。文档说的自动绑定这才真正发生;建议同步因看到已绑定而不再冗余提示。无 ADR 冲突——这是让代码符合既有 spec/ADR,不是改策略(package isDefault → suggestion 那条不变)。everyone一项(框架现在自己绑),只保留框架无法推断的 7 条 persona 绑定。改动:
packages/plugins/plugin-security/src/security-plugin.ts、examples/app-showcase/src/security/bind-position-sets.ts、examples/app-showcase/src/data/seed/index.ts。验证
turbo build干净;dogfood 全套 262 通过(everyone←member_default baseline 不回归)。objectstack dev) —— fresh boot 后:everyone ← showcase_member_default由框架创建(binding idpps_*,非 app glue 的ppsb_*)——package isDefault 现在真的自动绑。sys_audience_binding_suggestion= 0(冗余提示消失)。kernel:bootstrapped)。关联
#2926(E2E 暴露这两个时序 bug)· #2983(用 kernel:listening 临时兜住,本 PR 做正解)· ADR-0090 D5。
🤖 Generated with Claude Code
Generated by Claude Code