Skip to content

fix(spec,plugins): 清扫 auth/session 一族的槽查找 —— 31 处类型化,并揪出 user-import 的 metadata reader 指着一个没有该方法的服务 (#4251) - #4361

Merged
os-zhuang merged 1 commit into
mainfrom
claude/4251-b2-auth-session-slot-sweep
Jul 31, 2026
Merged

fix(spec,plugins): 清扫 auth/session 一族的槽查找 —— 31 处类型化,并揪出 user-import 的 metadata reader 指着一个没有该方法的服务 (#4251)#4361
os-zhuang merged 1 commit into
mainfrom
claude/4251-b2-auth-session-slot-sweep

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

#4251 清扫的 B2 批次 —— auth / session 一族,该族里的擦除一个不留。基线棘轮 171 → 140 站点、40 → 37 文件,三个文件全部退出祖父名单。

文件 站点
plugins/plugin-auth/src/auth-plugin.ts 20
plugins/plugin-hono-server/src/current-user-endpoints.ts 10
plugins/plugin-security/src/security-plugin.ts 1

产出

POST /admin/import-users 在探测一个该服务从来没有的方法。 这条路由解析 metadata 槽,然后用 metadataService?.getMetaItem 决定要不要把导入的字段强制转换依赖传下去:

const metadataService: any = (() => {
  try { return ctx.getService?.('metadata'); } catch { return undefined; }
})();
...(metadataService?.getMetaItem ? { getMetaItem:  } : {}),

getMetaItemprotocol 的方法 —— ObjectStackProtocolImplementation,由 MetadataProtocolPlugin 注册在 protocol 槽下。占着 metadata 槽的是 MetadataManager,它没有、也从来没有过这个方法。所以这个三元判断在任何部署上都是假,依赖从未传入:导入行未经类型强制就写进了 sys_user,而声称相反的分支就摆在那里。

这和 #4127 那个死掉的 automation.trigger#4321registerInMemory 探测是同一个形状 —— 代码宣称、运行时给不出的能力,被 any 一直盖着。把这次查找类型化到 IMetadataService,正是让这个死探测变成编译错误的那一步。 路由现在读 protocol

/me/apps 伸进了 ObjectQL 的私有状态。 它读的是 (ctx.getService('objectql') as any)?._registry,而同一个文件里往上两个 handler 的 /auth/me/permissions,读的是同一个对象同一个字段上的公开 registry getter。两处现在都走公开访问器。唯一那个 stub 了 _registry 的测试,钉住的就是这次私有伸手,改 stub registry

契约:按证据补

IDataEngine 的读方法(find / findOne / count / aggregate)现在声明了它们一直在接受的尾随 options?: BaseEngineOptions 参数。ObjectQL 自己给 EngineReadOptions 写的注释就是理由:

读方法历史上把执行上下文放在 query 里,写方法放在尾随的 options.context 里 …… 同一个 { context } 对象作为 insert 的第 3 个参数是对的,作为 find 的第 3 个参数却被静默丢弃 —— 一个本意为 isSystem 的绕过就这么凭空消失了。

引擎两条通道都收(options.context 优先)。但契约只暴露了 query 那条,于是每个用尾随通道的调用方 —— 包括 current-user endpoints 的权限集加载器 —— 只能靠把查找擦成 any 才能够到它。这正是本 issue 在扫的那种擦除,只不过是在它的成因那一层。

加一个可选尾随参数不破坏任何实现方(data-engine.test.ts 里既有的"最小实现"用例本身就证明少写参数仍然满足接口),也不破坏任何调用方。BaseEngineOptions 本来就已导出 —— 只是躺在 "legacy/deprecated" 标题下无人使用,这也正是契约当初去找、没找到的原因;现在把它挪到其余 QueryAST 对齐类型旁边,并附上理由。新增一个 spec 测试,把这个参数钉在调用点上 —— 旧契约当初拒绝它的那个位置。

契约够不到的地方,逃生口是具名的

有三个槽今天还给不出 spec 类型。每一个都拿到一个窄的、有文档的本地接口,而不是 any —— 沿用 plugin-audit 的写法(MessagingEmitSurface / AuditI18nSurface):

  • security.permissionsPermissionEvaluatorSurface。plugin-security 的 PermissionEvaluator;plugin-hono-server 不能对一个可选插件产生运行时依赖(下面那些 !evaluator 分支就是它的缺席)。
  • settingsSettingsReadSurface。service-settings 同理。
  • objectql 超出 IDataEngine 的部分 → EngineRegistrySurface(registry / getSchema)与 EngineExtensionSurface(registerHook / registerMiddleware)。

最后这条是刻意留的范围,不是遗漏。@objectstack/runtimeDomainHandlerContextgetObjectQL 那段现存记录写得很清楚:ObjectQL 确实比 IDataEngine 宽,更宽的那部分没人写过契约,把整个东西标成 IDataEngine 会是"看着更舒服的那个谎",把缺口埋在一堆 cast 底下。这些声明就是那份契约将来要据以书写的具体输入 —— 也是它落地时(B3)要删掉的东西。

顺带一提:SettingsReadSurface 一开始漏了 subscribe,编译器当场点出 6 个调用点(brand name / SMS locale / auth 命名空间的实时重绑)。any 不会说一个字。SettingsChangeHandler / SettingsUnsubscribe@objectstack/spec/system 已有公开类型,所以直接复用而不是另起一套形状。

范围外,只报告不修

规则仍然看不见的第三种形状,与已记录的"包装函数返回注解"残留不同,而且不需要类型信息就能抓:

let ql: any;
ql = ctx.getService('objectql');   // 声明符上没注解、没类型实参、没有 as

全仓约 20 处(runtime/app-plugin.ts ×4、cloud-connection/*core/fallbacks/authored-translation-sync.ts …)。细节回帖到 #4251

验证

  • pnpm check:slot-lookup (强制模式) → ✓ ratchet holds: 140 unswept site(s) in 37 file(s), none new;baseline key set verified against 6a67d7a: no files added
  • eslint --no-inline-config 全部改动文件 —— 干净
  • 全仓 pnpm typecheck —— 110/110 任务通过
  • @objectstack/spec 7157 tests / 278 filesobjectql 1394 / 87runtime 951 / 66plugin-auth 579 / 26plugin-security 677 / 32plugin-hono-server 135 / 12 —— 全绿

🤖 Generated with Claude Code

Batch B2 of the #4251 sweep: every service-lookup erasure in the
auth/session family. plugin-auth/auth-plugin.ts (20),
plugin-hono-server/current-user-endpoints.ts (10) and
plugin-security/security-plugin.ts (1) now pass the slot's contract type;
the ratchet baseline drops 171 -> 140 sites, 40 -> 37 files, and all three
files leave the grandfather list.

The yield: POST /admin/import-users resolved the `metadata` slot and probed
`metadataService?.getMetaItem` to decide whether to pass the import's
field-coercion dependency. `getMetaItem` is a PROTOCOL method
(ObjectStackProtocolImplementation, registered under `protocol`);
MetadataManager, which occupies `metadata`, has never had it. The probe was
false on every deployment and the dep was never passed -- imported rows
reached sys_user uncoerced, with the branch claiming otherwise sitting
right there. Same shape as #4127's dead automation.trigger. The route reads
`protocol` now.

/me/apps reached ObjectQL's PRIVATE `_registry` through `as any` while
/auth/me/permissions, two handlers up in the same file, read the public
`registry` getter over the same field of the same object. Both read the
public accessor now; the one test that stubbed `_registry` was pinning that
private reach and stubs `registry`.

Contract, from evidence: IDataEngine's read methods (find / findOne /
count / aggregate) declare the trailing `options?: BaseEngineOptions`
argument they have always accepted. ObjectQL's own doc explains why it
exists -- the same `{ context }` object was correct as insert's 3rd
argument and SILENTLY DROPPED as find's, so an intended isSystem bypass
just vanished. The contract exposed only query.context, so callers using
the trailing channel could reach it only by erasing the lookup. Adding an
optional trailing parameter breaks no implementor or caller;
BaseEngineOptions was already exported but sat unused under the
legacy/deprecated heading, and moves up with the rationale attached. One
new spec test pins the argument at the call site.

Where the contract does not reach, the escape hatch is named rather than
`any`: PermissionEvaluatorSurface (security.permissions),
SettingsReadSurface (settings), EngineRegistrySurface /
EngineExtensionSurface (objectql beyond IDataEngine). That last one is
deliberate scope -- the standing record on getObjectQL in @objectstack/
runtime says ObjectQL is genuinely wider than IDataEngine and typing the
whole thing IDataEngine would be the more comfortable-looking lie. These
declarations are what that contract gets written from, and what it deletes.

Verified: full-repo typecheck 110/110; spec 7157/278, objectql 1394/87,
runtime 951/66, plugin-auth 579/26, plugin-security 677/32,
plugin-hono-server 135/12; eslint clean on every changed file;
check:slot-lookup 140 sites in 37 files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 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 31, 2026 8:52am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data tests tooling size/m and removed documentation Improvements or additions to documentation protocol:data tests tooling labels Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/plugin-auth, @objectstack/plugin-hono-server, @objectstack/plugin-security, @objectstack/spec.

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

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/plugin-auth, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/plugin-hono-server, @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/plugin-security, packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-auth, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/access-recipes.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-auth, @objectstack/plugin-hono-server)
  • content/docs/permissions/authorization.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/permissions/explain.mdx (via @objectstack/plugin-security)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/permissions/sso.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-auth, @objectstack/plugin-hono-server, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/plugin-auth, @objectstack/plugin-hono-server, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/plugin-auth, @objectstack/plugin-hono-server)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-auth, @objectstack/plugin-hono-server, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/plugin-hono-server, @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth, @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/audience-based-interfaces.mdx (via packages/plugins/plugin-security)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

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 changed the title fix(spec,plugins): sweep the auth/session slot lookups — 31 sites typed, and the user-import metadata reader was pointed at a service that never had the method (#4251) fix(spec,plugins): 清扫 auth/session 一族的槽查找 —— 31 处类型化,并揪出 user-import 的 metadata reader 指着一个没有该方法的服务 (#4251) Jul 31, 2026
@os-zhuang
os-zhuang merged commit c54c822 into main Jul 31, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/4251-b2-auth-session-slot-sweep branch July 31, 2026 09:08
xuyushun441-sys pushed a commit that referenced this pull request Jul 31, 2026
…ract exports (#4251 B3)

`check:api-surface` is spec's public-API snapshot gate, and it reported
exactly what this PR does: "0 breaking (removed/narrowed), 2 added". The
two are IObjectQLEngine and EngineSchemaRegistryView; the regenerated
snapshot diff is +2 lines, -0 -- purely additive, matching the gate's own
count.

Missed because I ran spec's build and tests but not its check:* gates.
#4361 ran all of them; this PR did not. All 16 now pass locally
(check:exported-any included -- the contract's deliberate `any`s at the
framework-handle and engine-local-shape edges are within its allowance).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 31, 2026
…之,七个本地 stand-in 退场 (#4251 B3) (#4404)

* feat(spec,objectql): IObjectQLEngine -- the objectql slot's contract exists, the class implements it, the seven local stand-ins are deleted (#4251 B3)

The ledger can finally say what each of ObjectQL's two registration names
means: `data` stays IDataEngine (the data plane); `objectql` resolves to
IObjectQLEngine -- schema access (getSchema/getObject/registry), actions
(registerAction/removeActionsByPackage/executeAction), hook & middleware
seams (registerHook/unregisterHooksByPackage/registerFunction/
registerMiddleware/bindHooks), the first-wins default runners and hook
metrics, boot wiring (registerDriver/setDatasourceMapping/registerApp),
and ops probes (checkDriversHealth/wasDatastoreCreatedFromEmpty/
invalidateDataMigrationFlags). The ledger test pins the relation:
objectql strictly WIDENS data, deliberately no longer equal.

Why implements is the point: the honest state for two batches -- recorded
on DomainHandlerContext.getObjectQL -- was that the wider surface had no
contract, so seven consumer-local stand-ins accumulated
(AppEngineSurface, EngineRegistrySurface, EngineExtensionSurface,
SecurityEngineSurface, FreshDatastoreEngine, the dispatcher's inline
checkDriversHealth slice, getObjectQL: any). Each was honest and each was
an UNCHECKED claim: getService<Surface>() is an assertion, so an engine
rename would break every consumer at runtime with zero compile errors.
`ObjectQL implements IObjectQLEngine` turns all of them into one
compiler-verified claim; all seven are deleted, and getObjectQL is typed
Promise<IObjectQLEngine | null> end to end.

Evidence bar unchanged: every member has a cross-package consumer through
the slot; triggerHooks (cross-package only in tests) stays off.

_registry never leaves the engine package now: plugin-security's five
declared-metadata readers reached the private field through `any` -- the
same reach /me/apps had in B2 -- all migrated to the public getter the
contract declares, test doubles included.

IMetadataService gains subscribe?/loadMany? -- implemented by
MetadataManager beside watch all along, reached only via `any` by
ObjectQLPlugin's metadata bridge. With them declared, that bridge's six
lookups and metadata-protocol's objectql lookup carry contract types and
both files leave the grandfather list: baseline 167 -> 159 sites,
36 -> 34 files.

Verified: spec build + 7198/282; objectql build (the implements check) +
1464/89; runtime 1015/70; plugin-security 677/32; plugin-hono-server
135/12; plugin-auth 579/26; platform-objects 254/8; metadata 281/13;
metadata-protocol 136/21; all eight dts builds; ratchet holds 159/34
none new; eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(spec,objectql,plugin-security): CI round-trip fixes -- and the implements check caught a second spec-internal double (#4251 B3)

Three fixes, all caught by gates:

1. security-plugin:880 -- the contract's getSchema returns `unknown`;
   narrow to EngineOwnedSchemaLike at the guard call (CI Build Core; my
   local batch had been aborted by an earlier failure and I re-ran only
   the failed package -- the DEBT-package lesson, second verse).

2. objectql plugin.ts:1583 -- optional-member narrowing does not survive
   into a closure (TS2722); take a bound reference under the guard.

3. IMetadataService.subscribe -- the first draft reused `watch`'s
   callback type, and `MetadataManager implements IMetadataService`
   REJECTED it: subscribe relays the persistence-side MetadataWatchEvent
   (add/changed/deleted + path/stats), not watch's registration-level
   events. The check working exactly as intended, on its first day.
   Fixing it exposed that spec carries TWO types named MetadataWatchEvent
   with different shapes (system/metadata-persistence.zod vs
   kernel/metadata-loader.zod) -- the same double-source shape as the
   http-server shadow, both alive this time. Reported on #4251; merging
   them is its own change. The contract now imports the persistence one
   the implementation uses, with the trap documented at the import.

Verified: all nine touched packages' dts builds in ONE uninterrupted
batch; spec 7198/282, objectql 1464/89, metadata 281/13,
plugin-security 677/32; eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(spec): regenerate the api-surface snapshot for the two new contract exports (#4251 B3)

`check:api-surface` is spec's public-API snapshot gate, and it reported
exactly what this PR does: "0 breaking (removed/narrowed), 2 added". The
two are IObjectQLEngine and EngineSchemaRegistryView; the regenerated
snapshot diff is +2 lines, -0 -- purely additive, matching the gate's own
count.

Missed because I ran spec's build and tests but not its check:* gates.
#4361 ran all of them; this PR did not. All 16 now pass locally
(check:exported-any included -- the contract's deliberate `any`s at the
framework-handle and engine-local-shape edges are within its allowance).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant