Skip to content

fix(runtime,spec): 让 @objectstack/runtime 的 src 真正被 tsc 读 —— 修 25 条并接进 turbo typecheck (#4311) - #5045

Merged
xuyushun441-sys merged 2 commits into
mainfrom
claude/issue-4311-runtime-typecheck
Aug 4, 2026
Merged

fix(runtime,spec): 让 @objectstack/runtime 的 src 真正被 tsc 读 —— 修 25 条并接进 turbo typecheck (#4311)#5045
xuyushun441-sys merged 2 commits into
mainfrom
claude/issue-4311-runtime-typecheck

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Part of #4311 — 第一片:@objectstack/runtimesrc 层(维护者已裁决按包切片)。照 #4855 / PR #5002 的毕业模式:修完 → 接线 → 同 PR 删台账条目。

问题

scripts/check-type-check-coverage.mjs 的 DEBT 台账把 @objectstack/runtime 记作:

'@objectstack/runtime': {
errors: 18,
note: 'noise only (TS6133 unused); no code-tier finding in #4311.',
},

COVERED 不变式接受「声明了 typecheck script」「有一条带实测数的 DEBT 条目」,runtime 走的是后一条 —— 闸门诚实地记录了这个包没被检查,但记录不等于执行。runtime 是 dispatcher / domain handlers / action 执行的所在地,是本仓最重的运行时包之一,它的 src/ 至今没有任何 tsc 读过。

实测:18 → 25,而且「noise only」是错的

台账冻结于 b07d829(2026-07-31);我在最新 main 上实测 25 条。漂移方向与 #4855(12 → 14)一致,再次印证「用记录顶替执行,记录就会漂」。

但比数字更重要的是分类被记错了:

类别实测台账所记
TS6133 未用形参 / 导入(noise)1818(全部)
TS2339 属性不存在(code-tier)70(「no code-tier finding」)

7 条 TS2339 全部落在 src/domains/packages.ts,是一处真实的契约缺陷,不是噪音。

真缺陷:EngineSchemaRegistryView 少声明了六个成员

src/domains/packages.ts(99,40): error TS2339: Property 'getPackage' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(111,32): error TS2339: Property 'installPackage' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(121,34): error TS2339: Property 'enablePackage' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(134,34): error TS2339: Property 'disablePackage' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(437,34): error TS2339: Property 'getPackage' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(475,34): error TS2339: Property 'updatePackageManifest' does not exist on type 'EngineSchemaRegistryView'.
src/domains/packages.ts(487,46): error TS2339: Property 'uninstallPackage' does not exist on type 'EngineSchemaRegistryView'.

#4404 (#4251 B3) 把 objectql 槽的契约落地为 IObjectQLEngine / EngineSchemaRegistryView,文档写的是「the eight members reached through the objectql slot from outside the engine package」。这句话在写下时就不成立:

  • SchemaRegistry(packages/objectql/src/registry.ts:1576-1712)一直实现着这六个成员;
  • 引擎包之外一直有三个包在调它们:runtime/packages domain handler(整个 /packages REST 家族的 owner)、metadata-protocolinstallPackage/updatePackageManifest 原语(protocol.ts:9706,9754)、service-package 的 hydration(index.ts:213,243)。

为什么没人发现:这三个包当时(和现在)都没有 typecheck —— runtime 与 metadata-protocol 都在 DEBT 台账里。契约的收窄之所以能编译通过,只是因为没有任何 tsc 读过调用方。这正是 #4311 议题正文里那句话的字面重演:「这类收窄本应让传旧形状的调用编译失败 —— 而它们至今全绿,因为没有任何 tsc 读过这些文件」。

修在生产者,不在消费者

按契约优先(Prime Directive #12),修法是给 spec 的契约补齐声明,而不是在 runtime 侧写 (registry as any).installPackage:

// ── Package lifecycle (the in-memory half of `/packages`) ────────────getPackage(id: string): unknown;installPackage(manifest: unknown,settings?: Record<string,unknown>): unknown;uninstallPackage(id: string): boolean;enablePackage(id: string): unknown;disablePackage(id: string): unknown;updatePackageManifest(id: string,patch: {name?: string;description?: string;version?: string}): unknown;

参数/返回类型沿用该文件既有政策(engine-local 类型 InstalledPackage / ObjectStackManifest 一律写 unknown,spec 不依赖 engine 包),成员写成 required 而非 optional —— 与该文件已写明的立场一致:「this contract describes THAT engine — the slot's actual occupant — not a hypothetical minimal one」。ObjectQL implements IObjectQLEngineimplements 校验仍然通过(见下方 objectql 的 typecheck 绿)。

零运行时改动:没有任何实现、调用点或响应形状移动;只是让声明追上了一直存在的实现。

另外 18 条 TS6133 —— 逐条说明,没有一条是「加 ! 闭嘴」

本片一个 ! 也没有加,一个 ?. 也没有加(bang_justifications_count = 0)。TS18048 possibly-undefined 那一类全部在 test 层(TEST_DEBT 的 220 条),本片不碰。src 层的 18 条全是未用符号,三种处理:

位置数量处理为什么这么修
action-execution.ts 13 个导出纯函数的首参 deps13改名 _deps该模块的约定是每个导出 helper 一律 deps 优先(23 个函数如此),13 个纯谓词/纯构造函数用不到它。同文件 reconcileActionRegistrations(:1172)本来就写着 _deps —— 这是文件内既有先例,不是我发明的写法。删参会改导出函数签名,而调用它们的测试是按位置传参且不受类型检查,静默错位风险远大于收益。
domains/auth.tspath / method / body3改名 _path / _method / _body + 补注释#4113 删掉 mock session 之后,/auth 不再按子路径分流,而是把 context.request 整个交给 auth service(authService.handleRequest(context.request)),由它自己路由 —— 三个参数是那次删除的残留。保留形参是为了与其它 domain handler 的位置签名对齐(createAuthDomain 就是按位置传的)。
domains/meta.tsimport * as actionExec1删除该 import全文件零引用(grep 仅命中 import 行本身)。action-execution.ts 顶层无副作用(只有函数声明和一个模块级 Set),删除不改变任何加载行为。
domains/mcp.tstoMcpWebRequest(deps, …)1改名 _deps模块私有函数,同样遵循该文件 deps 优先的调用约定。

接进强制执行

"typecheck": "tsc --noEmit"

外加删掉 check-type-check-coverage.mjs 里 runtime 的 DEBT 条目(毕业动作;不删则 RECONCILED 不变式失败)。

✓ check:type-check-coverage --self-test — 18 semantic case(s) hold.
check-type-check-coverage: OK — 62/77 workspace packages type-checked (plus the root),
15 in the DEBT ledger (358 frozen raw errors), 1 exempt.
test layer: 21 package(s) still exclude their own tests (652 files, 2243 frozen raw errors in TEST_DEBT).

覆盖率 61/77 → 62/77,DEBT 16 → 15 个包。turbo.jsonlint.yml 未改动(RUNNABLE 不变式已在管它们)。

TEST_DEBT 未被本片激活 —— 已确认

runtime 的 tsconfig.json 仍然 exclude: ["node_modules","dist","**/*.spec.ts","**/*.test.ts"],本 PR 没有动它。所以接上 tsc --noEmit 只让 src/**/* 进入检查,66 个测试文件的 220 条错误仍然被 TEST_DEBT 条目冻结着,TESTS_COVERED 不变式照常成立(上面的实跑输出里 test 层仍是 21 个包 / 652 文件 / 2243 条,与 main 逐字相同)。这正是台账机制既有约定所要求的:DEBT 是「src 不检查」,TEST_DEBT 是「src 检查、测试被藏」,两者独立,src 毕业不牵动 test 层。

只订正了 TEST_DEBT 条目里一句因本 PR 而失真的注释(「Also in DEBT: its src does not check either.」→ 记明 src 已在 #4311 毕业),实测数字 tests: 66, errors: 220 原封未动 —— 台账的诚实性要求删掉已经变假的话,而不是让它留在那里烂掉。

反向验证

src/domains/packages.ts 里给 registry.enablePackage(id) 塞一个多余实参,走真实 CI 入口:

$ npx turbo run typecheck --filter=@objectstack/runtime
@objectstack/runtime:typecheck: src/domains/packages.ts(121,52): error TS2554: Expected 1 arguments, but got 2.
Failed: @objectstack/runtime#typecheck

值得注意的是:判红靠的正是本 PR 新加的那条声明 —— 说明补进契约的六个成员是承重的,不是装饰(与 #5002: Flow 优于 as const 的论证同形)。

revert 后:

@objectstack/runtime:typecheck: cache hit, replaying logs decc78ab0624d82d
Tasks: 28 successful, 28 total

decc78ab0624d82d 与注入前那次绿跑的 turbo hash 逐字相同 —— 状态被精确还原,绿不是陈旧缓存蒙对的(照搬 #5002 的证法)。

测试与门禁

$ pnpm --filter @objectstack/runtime test
Test Files 82 passed (82)
Tests 1131 passed (1131)
$ npx turbo run typecheck --filter={objectql,spec,service-package,plugin-security,runtime}
Tasks: 32 successful, 32 total # 契约改动的下游全绿,含 ObjectQL 的 implements 校验
$ pnpm --filter @objectstack/spec check:generated
✓ All 8 generated artifacts are up to date. # 接口加成员不改 api-surface(它只记导出名)
$ eslint . --no-inline-config # 干净

零行为改动:所有修改要么是类型声明补齐,要么是未用符号改名/删除。1131 个测试逐个通过,数量与 main 一致。

改动范围

packages/runtime/package.json | 1 +
packages/runtime/src/action-execution.ts | 26 +++++++-------
packages/runtime/src/domains/auth.ts | 9 ++++-
packages/runtime/src/domains/mcp.ts | 2 +-
packages/runtime/src/domains/meta.ts | 1 -
packages/spec/src/contracts/objectql-engine.ts | 31 +++++++++++++++-
scripts/check-type-check-coverage.mjs | 6 +---
  • scripts/check-type-check-coverage.mjs —— 根目录共享文件,只删 runtime 的 4 行 DEBT 条目 + 改 TEST_DEBT 的一句注释。闸门语义零改动。
  • packages/spec/src/contracts/objectql-engine.ts —— 超出「只动 runtime」的落点,但按 Prime Directive Add comprehensive test suite for Zod schema validation #12 这条缺陷的生产者就在 spec;在消费者侧 as any 会把一个真实的契约漏声明永久藏进 runtime。
  • .changeset/runtime-typecheck-wired.md —— @objectstack/spec patch(导出接口有新增成员,.d.ts 对消费者可见);runtime 侧纯类型标注 + dev script,不发版。

留给后续切片的

  • runtime 的 test 层 220 条(TEST_DEBT):本片按分派只做 src,未动 tsconfig 的 exclude。
  • 一条观察,不立单:/packages 的 enable/disable/get/uninstall 四条路由直接写 in-memory registry,而 install/update 已经优先走 protocol service(持久化到 sys_packages)、只在服务缺席时回落 registry。四条路由的持久化对称性看着像缺口,但修它要改运行时行为,超出「类型修复不得改变测试行为」的边界,本 PR 不碰。

Generated by Claude Code

…进 turbo typecheck (#4311)
Part of #4311 (第一片:@objectstack/runtime 的 src 层)。
- packages/runtime: 新增 `typecheck: tsc --noEmit`,清掉实测的 25 条错误
(18 条 TS6133 未用形参/导入,7 条 TS2339 真契约缺陷)。
- packages/spec: `EngineSchemaRegistryView` 补齐六个 package-lifecycle 成员
—— SchemaRegistry 一直实现、三个包一直在调,#4404 落契约时漏declare,
因为 runtime 没有 typecheck 所以没人发现。
- scripts/check-type-check-coverage.mjs: 删 runtime 的 DEBT 条目(毕业要求,
否则 RECONCILED 不变式失败),并订正 TEST_DEBT 里已失真的一句注释。
覆盖率 61/77 → 62/77,DEBT 16 → 15 个包。TEST_DEBT 未被激活(tsconfig 仍
exclude 测试文件,220 条留给后续切片)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018iARDqtrhQgz6fVHDeDkbQ
@vercel

vercelBot commented Aug 4, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 4, 2026 12:43am

Request Review

@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file tooling labels Aug 4, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/runtime, @objectstack/spec.

113 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 packages/runtime, @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/runtime, @objectstack/spec)
  • content/docs/api/wire-format.mdx(via @objectstack/runtime)
  • 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 @objectstack/runtime, 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 @objectstack/runtime, packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/runtime, @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/runtime, @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/spec)
  • content/docs/deployment/index.mdx(via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx(via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx(via @objectstack/runtime)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/deployment/vercel.mdx(via @objectstack/runtime)
  • 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/runtime, @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/runtime, @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 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/spec)
  • content/docs/kernel/services.mdx(via @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/runtime)
  • content/docs/permissions/authorization.mdx(via packages/runtime, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @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/spec)
  • 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/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/runtime, @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/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.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/runtime, @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/spec)
  • content/docs/releases/v17.mdx(via @objectstack/runtime, @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @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.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filedocumentationImprovements or additions to documentationsize/stooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@claude