fix(objectql): bridge late-registered manifest objects into the metadata service#3428
Merged
Conversation
…ata service Marketplace-installed template packages register through the manifest service on kernel:ready (rehydrate) or an HTTP request (install), but the one-shot SchemaRegistry-to-metadata bridge runs once during ObjectQLPlugin.start() - so their objects only ever reached the ObjectQL registry. Every IMetadataService consumer (AI describe_object, Studio object lists, metadata.listObjects) missed them; only the seed loader had grown an engine-side fallback (#3422). The manifest service's register now bridges the manifest's own objects (registry-resolved, so both objects forms and extension merges come out canonical with _packageId stamped) into the metadata service: - resolved at call time: at objectql init the metadata service may not be registered yet - register('object', name, obj, { notify: false }) - same #3112 rationale as the startup bridge: announcing would loop the definitions back through our own subscribe('object') handler and overwrite provenance with 'metadata-service' - entries it did not bridge itself are never clobbered; its own copy is refreshed on same-package re-install so a hot marketplace upgrade stays fresh - armed only after start() ran the one-shot bridge, and never on project kernels (same environmentId gate) - boot-time behavior is unchanged register returns the bridge promise; marketplace install/rehydrate await it so metadata reads right after a 200 are deterministic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
added a commit
that referenced
this pull request
Jul 24, 2026
…ls too (#3436) The per-manifest bridge added for marketplace installs (#3428) armed itself inside the same `environmentId === undefined` gate as the one-shot startup bridge - but `os dev` boots the kernel project-scoped (environmentId 'env_local'), which is marketplace install-local's primary home, so the fix was inert exactly where it matters. Caught by browser-dogfooding the install flow: the install succeeded, yet the process never logged a bridge pass and the flag could never arm. The gate is correct for the one-shot bridge (it copies the ENTIRE process-wide SchemaRegistry, which would leak sibling-project objects on multi-environment servers) but does not apply to the per-manifest bridge: it only copies the objects of the one package this kernel just registered - nothing to leak. Arming now happens unconditionally at the end of start(); boot-time behavior on every kernel shape is unchanged (the flag still flips only after the startup path has run) and the one-shot bridge keeps its gate. Regression test: a project-scoped kernel (environmentId 'env_local' - the exact `os dev` shape) now asserts a post-bootstrap manifest.register lands its objects in the metadata service; red before this change. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
问题
Marketplace 安装的模板包对象(manifest 服务 →
ql.registerApp)只进 ObjectQL registry,永远不进 metadata 服务(IMetadataService):bridgeObjectsToMetadataService只在ObjectQLPlugin.start()里一次性运行,而 marketplace 的 install / ledger rehydrate 都发生在kernel:ready之后。后果:所有 IMetadataService 消费者对 marketplace 对象 miss——AI
describe_object、Studio 对象清单、metadata.listObjects等。种子加载器的引用图盲区已由 #3422 用 engine.getSchema fallback 单独修复,但那只救了 seed 一条路。修复
manifest 服务的
register在注册进 engine registry 后,把该 manifest 自己的对象 bridge 进 metadata 服务(packages/objectql/src/plugin.ts):registry.getAllObjects(packageId)):数组/映射两种objects形态、extension 合并、applySystemFields/provisionPrimary归一化都拿到规范形状,且盖上_packageId印记;register('object', name, obj, { notify: false })——与启动 bridge 同一 MetadataManager.register() never notifies subscribe() watchers — runtime consumers go stale on every non-saveMetaItem write #3112 通知契约理由:定义本来就来自 SchemaRegistry,announce 会经我们自己的subscribe('object')回环并把 provenance 覆盖成metadata-service;start()跑完一次性 bridge 后才生效(启动期行为零变化,启动期注册仍由一次性 bridge 覆盖),且项目级 kernel(environmentId有值)永不生效——与一次性 bridge 同门;register返回 bridge promise(从不 reject);marketplace install/rehydrate 两处 await 它,安装返回 200 后立刻读 metadata 是确定性的(packages/cloud-connection/src/marketplace-install-local-plugin.ts)。测试
plugin.integration.test.ts新增 4 个真 kernel 集成测试(late manifest.register bridges objects to the metadata service):metadata.getObject('crm_contact')返回 registry 解析形状(_packageId印记、字段完整),listObjects可见;门先证红:还原
plugin.ts后测试 1/2 失败、3/4 通过(护栏测试本就该绿),确认非假绿。@objectstack/objectql72 文件 / 1040 测试全绿;@objectstack/cloud-connection9 文件 / 55 测试全绿;两包 build(含 dts)通过。🤖 Generated with Claude Code