Skip to content

refactor(spec,cli,runtime)!: 退役 crypto.hash 能力 —— 声明四层、构建期还自动推断,沙箱从没实现 (#4391) - #4871

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-4391-crypto-hash-retire
Aug 3, 2026
Merged

refactor(spec,cli,runtime)!: 退役 crypto.hash 能力 —— 声明四层、构建期还自动推断,沙箱从没实现 (#4391)#4871
os-zhuang merged 3 commits into
mainfrom
claude/issue-4391-crypto-hash-retire

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #4391

裁决依据(以及一条已作废的 PM 裁定)

本单方向以 维护者 2026-08-02 09:50Z 的裁决为准:remove

⚠️ 本单评论区有一条已作废的裁定需要说明,免得后来者读串:

时间 内容 效力
08-02 09:50Z 维护者裁决:remove 权威,本 PR 照此执行
08-02 19:52Z 另一 PM 会话「裁定走路线 A(实现 WebCrypto)」 ❌ 已作废
08-02 19:54Z 同一 PM 自行撤回上条,确认以维护者 remove 为准,退回队列交 spec 车道
08-03 09:13Z 协议线 PM 接手,分支 claude/issue-4391-crypto-hash-retire

那条撤回自陈的三点误判值得留档,因为它们正是本单最容易走偏的地方:把「签名已写好」误读成需求信号(那只是声明面自己长出来的);算工时时漏了「在沙箱里实现 crypto 是扩大能力面与安全审查面」这项长期成本;以及在「防 AI 犯错」轴上得出了相反结论 —— 实现它只是把炸点从运行时挪走,却永久扩大了能力面。

维护者 remove 的理由(已写进 changeset):从未实现、调用即抛、零投诉 —— 对一个每次使用都抛错的能力,这本身就是最强的活性证据;构建期自动推断是危险的放大器(AI 写 hash 调用 → 能力被自动声明 → tsc 全绿 → 运行时才炸);删除声明与推断后,未知能力在作者时就红。真需要时按能力准入流程重提,实现先行、声明随实现走

改了什么(四层声明同批删)

位置 处置
capability token spec/data/hook-body.zod.ts HookBodyCapability 枚举 删值(6 → 5)
文档串 同文件枚举 JSDoc 里那行 删,并就地记下移除原因与「随实现回来」
构建期推断 cli/utils/extract-hook-body.ts 删模式 + 两处联合类型 + @capabilities 覆盖白名单(共 4 处,原 issue 只点了 1 处)
运行时类型 runtime/sandbox/script-runner.ts ScriptContext.crypto.hash 删成员

保留:quickjs-runner.tscryptoObj.randomUUID(已实现、在用)一字未动。

同批清理的下游:content/docs/automation/hook-bodies.mdx(那句 _(not yet wired)_ —— 移除后它就成了新的谎言)、skills/objectstack-data/references/data-hooks.md(「exactly six」→ five + 表格行)、skills/objectstack-data/rules/hooks.md(六 token 列表)。后两个 skills 文件不在 issue 的范围清单里,是裸名扫描扫出来的。

退役形态:枚举收窄,不是 key 移除(以门禁实跑为准)

spec-property-retirement 的路由表实跑判定,结论是三条路都不走:

  • 没有 retiredKey() 墓碑 —— 墓碑是给 key 的,而 capabilities 这个 key 依然活着、依然被强制。给它上墓碑会把整个 key 打死。
  • 没有 UNKNOWN_KEY_GUIDANCE 条目 —— 那是 .strict() 对象的未知通道;这里被拒的是数组里的
  • 处方由枚举自己的 error map 承载,并按 object.managedBy'system' 退役先例(data/object.zod.ts)issue.input 为键:
export const HookBodyCapability = z.enum([...], {
  error: (issue) => (issue.input === 'crypto.hash' ? CRYPTO_HASH_RETIRED : undefined),
});

只有「曾经合法」的那个拼写会被告知 was removed;写错成 crypto.hsah 的作者拿到的仍是 zod 自己那条列出合法 token 的消息 —— 告诉他「你的值被退役了」属于误导(这条有独立 pin 测试)。

⚠️ 门禁实报:四张 ratchet 对枚举值收窄全部不可见

这是本 PR 最该被 review 的一条实测结论:

产物 记录粒度 本次是否变化
authorable-surface.json key 级(data/ScriptBody:capabilities) 0 行
json-schema.manifest.json def 名(data/HookBodyCapability 仍在) 0 行
api-surface.json 导出名 + kind 0 行
dual-source-exports.baseline.json 双源名 0 行

packages/spec/json-schema/ 本身 gitignore(实测 json-schema/data/HookBodyCapability.jsonenum 已收窄到 5 个值,但那是构建产物,不进版本库)。

实跑读数:

check:generated              PASS   ✓ All 8 generated artifacts are up to date.   (8/8)
check:authorable-surface     PASS
check:api-surface            PASS
check:liveness               PASS
check:empty-state            PASS
check:skill-examples         PASS
check:skill-refs / docs      PASS
check:dual-source-exports    PASS   0 accepted dual-source (baseline)   ← 要求为 0
check:variant-docs           PASS
check:strictness-ledger      PASS
check:exported-any           PASS
check:i18n / doc-authoring / release-notes / nul-bytes / adr-anchors / merge-driver / type-check-coverage   PASS

结论:没有任何一张基线能自动兜住这次移除 —— 兜住它的只有本 PR 新增的 pin 测试。这也是下面 sabotage 实跑非做不可的原因。

移动的生成物只有三处(check:generated 精确点名,照它的指示重生成):spec-changes.jsondocs/protocol-upgrade-guide.md、两页生成参考文档(data/hook-body.mdxui/action.mdx —— 枚举选项随之少一项)。

liveness 台账:不动,且这是对的

liveness/hook.jsonbody.{language,source,capabilities,timeoutMs} wired 一行保持原样 —— 台账走的是 schema shape 的属性,capabilities 键仍在 shape 里、仍然被强制。check:liveness(墓碑方向)与孤儿行检查(strict-removal 方向)双向 PASS,证明这里既不该留墓碑行、也没有留下孤儿行。

ADR-0087 conversion 逐条评估:需要,与 #4767 / #4783 / #4616 分属两侧

判断依据是 D2 的那一问:有没有可改写的作者源 / sys_metadata 行?

退役对象 有作者源? conversion
#4767 EnvironmentArtifact 双源导出 否(导出名/信封) 不需要
#4783 DriverCapabilities 能力位 否(运行时描述符,非作者写) 不需要
#4616 通知模板孤儿词表 否(纯导出,四仓零 reader) 不需要
#4734 enable.trash / enable.mru (stack 源 + 存量行) 需要
本单 body.capabilities 里的 'crypto.hash' 需要

capability token 是写在作者源 hook / action body capabilities: [] 数组里的,也会躺在已存的 sys_metadata 行里 —— 所以本单在 #4734 那一侧。注册:

  • D2 hook-body-crypto-hash-removed,surface 为 hook.body.capabilities / action.body.capabilities,同时走 hooks[]actions[](两者共用 HookBodySchema);
  • D3 挂进 MIGRATIONS_BY_MAJOR[17].conversionIds 并扩写该步 rationale;
  • retiredFromLoadPath: true —— 枚举当场拒绝,活作者在 parse 时就被教育,不做静默改写。这条 entry 存在是为了:①已存的 16.x / 17-rc 行重放干净(否则永远被打成 metadata_spec_invalid,把链上历史误标成当期违约);②os migrate meta --from 16 能改写作者源。这正是 object-enable-trash-mru-removed 的理由,只是深一层:token 是数组里的,stripKeys(只管顶层键)够不着,故写了专用 walker。

转换刻意不做的事:只剥掉 body.capabilities 里的死 token,不碰 body 源码里那行 ctx.crypto.hash(...)。那行调用从未返回过值,剥掉授权不会让任何还能跑的东西变坏;但把它一并「修好」会让作者失去唯一一个还在提醒他「这里有段死代码」的信号 —— 处方明确要求作者自己删。

fixture 按 disjointness 契约设计:crypto.uuid 在同一个数组里存活(证明是外科手术式剥离,不是整块删),stamp_lead 整条不被触碰,expectedNotices: 2(hook 一条 + action 一条)。

三仓消费方复核(裸名扫描,非 import 扫描)

扫描词:crypto.hashctx.crypto.hash、带引号的 'crypto.hash'HookBodyCapability

HEAD 命中
objectstack 本分支 全部在本 PR 内清理(spec 2 + cli 4 + runtime 1 + 手写文档 2 + skills 2 + 生成文档 4)
objectui 785b8a5 0
cloud 5df2c69 0

两个兄弟仓的空结果做了对照验证(用 capabilities 反查,objectui / cloud 各命中一大把,证明扫描器和路径没问题,不是 cd 把 cwd 重置成假空结果)。全程用 git -C REPO grep 形式,没有 cd

特别扫了 examples/skills/content/docs/:examples/ 零命中(没有教作者用它的示例),skills/ 两处、content/docs/ 手写两处,均已同批清理。

未发现任何真实运行时实现或真消费方 —— 对 packages/runtime/src/sandbox/quickjs-runner.tscrypto.hash 依旧无结果,installCtx 上只有 randomUUID,与 issue 正文一致。

Pin 测试 + sabotage 实跑

每一处移除都配了可失败的断言,并逐条 sabotage 实跑验证「复活即红」:

① 复活枚举值 → spec pin 必须红:

× does not offer `crypto.hash` as a capability token (#4391)
  AssertionError: expected [ 'api.read', 'api.write', …(4) ] to deeply equal [ 'api.read', 'api.write', …(3) ]
× rejects a body declaring `crypto.hash`, with the retirement prescription (#4391)
  AssertionError: expected true to be false
 Tests  2 failed | 13 passed (15)

② 复活 extractor 模式 → cli pin 必须红:

× does NOT infer a capability from ctx.crypto.hash (#4391)
  AssertionError: expected [ 'crypto.hash' ] to deeply equal []
× ignores crypto.hash in an explicit @capabilities override (#4391)
  AssertionError: expected [ 'api.read', 'crypto.hash', 'log' ] to deeply equal [ 'api.read', 'log' ]
 Tests  2 failed | 14 passed (16)

③ 往 VM seam 上装回 hash → runtime pin 必须红:

× the VM ctx.crypto exposes exactly randomUUID, under ANY grant (#4391)
  AssertionError: expected 'hash,randomUUID' to be 'randomUUID'
 Tests  1 failed | 57 passed (58)

④ 拆掉 D3 接线(把 id 从 conversionIds 摘掉)→ 链重放门禁必须红:

× hook-body-crypto-hash-removed: fixture.before → fixture.after via the chain
+           "crypto.hash",
 Test Files  1 failed | 3 passed (4)

四次 sabotage 全部按预期变红,随后逐一还原(git diff 已确认零 SABOTAGE 残留)。

一个诚实的说明:runtime 的类型 pin 目前是休眠

@objectstack/runtime 没有 typecheck 脚本(它在 scripts/check-type-check-coverage.mjs 的 DEBT 表里),所以纯类型级断言在这里永远不会被编译 —— 那种 pin 读起来像保障,实际给不了保障。因此 runtime 侧的 pin 写成了可执行的:在 VM 里 Object.keys(ctx.crypto) 枚举 seam 上真正装了什么,并且穷举而非只盯 hash(缺陷本质是「成员先于实现被声明」,所以任何新成员都该经过一次会同步更新此列表的 review)。类型级那条保留但注明休眠,待 runtime 接入 typecheck 时自动上膛。

全量验证读数

pnpm --filter @objectstack/spec    test    →  Test Files 295 passed (295) | Tests 7364 passed (7364)
pnpm --filter @objectstack/cli     test    →  Test Files  67 passed  (67) | Tests  588 passed  (588)
pnpm --filter @objectstack/runtime test    →  Test Files  80 passed  (80) | Tests 1094 passed (1094)
pnpm --filter @objectstack/spec    typecheck → PASS
pnpm --filter @objectstack/cli     typecheck → PASS
turbo run typecheck (全仓)                  →  Tasks: 122 successful, 122 total   exit=0
turbo run build   (cli + runtime 依赖图)    →  Tasks:  54 successful,  54 total   exit=0

重活全程串行在 flock /tmp/os-heavy-verify.lock 下,NODE_OPTIONS=--max-old-space-size,vitest --maxWorkers=2,turbo --concurrency=2

过程记录:CLI 首轮曾报 40 个文件失败,查明是未构建的兄弟包 dist(MODULE_NOT_FOUND),与本改动无关;merge 后又一次失败是 main 的 #4700 新增了 @objectstack/types/node 子路径而我的 pnpm install 早于 merge。两者都按「先证明不是自己的改动」处理:补 install + 重建依赖图后 67/67 全绿。

合并 main 的处理

merge 期间 main 前进 14 个提交(含 #4657#4756 等 spec 单)。按 AGENTS.md §3 git merge origin/main(未 rebase、未 force-push)

迁移话术(FROM → TO)

写了什么 现在怎么办
capabilities: ['crypto.hash'] 删掉这个 token。它从未授权成任何东西
await ctx.crypto.hash(algo, data) 删掉这次调用。它从未返回过值 —— 今天能跑的代码没有一行依赖它
确实需要哈希 在 host 侧做(Connector recipe,或引擎侧 hook)。沙箱内哈希须按能力准入流程重开,实现先行

一句话:两个都删os migrate meta --from 16 自动剥掉 token;那行死调用是作者自己要删的(转换刻意不改 body 源码,理由见上)。

定级 @objectstack/spec / @objectstack/cli / @objectstack/runtimemajor,按 #4535 §5 三问在 changeset 里逐条自证(TS2305 / TS2339 的具体触发形状、元数据迁移的有无、形状变更属枚举收窄而非 key 移除)。

范围外发现

⛔ 全程未碰 content/docs/releases/

claude added 2 commits August 3, 2026 10:51
…#4391)

`crypto.hash` 由四层声明、零层实现:`HookBodyCapability` 枚举、枚举旁文档表、
CLI 提取器的构建期推断、`ScriptContext.crypto.hash` 签名 —— 而 `installCtx` 只
往 VM 的 `ctx.crypto` 装了 `randomUUID`,该 token 唯一授权的调用每次都在 VM 里抛。

构建期推断是危险的放大器:作者写下 `ctx.crypto.hash(...)`,提取器替他把能力加进
`capabilities`,`os build` 因此全绿,直到运行时才炸。维护者裁决 remove:从未实现、
调用即抛、零投诉 —— 对一个每次使用都抛错的能力,这本身就是最强的活性证据;在沙箱里
实现 crypto 会扩大能力面与安全审查面,无业务拉动不做。实现先行、声明随实现走。

同批删除四处声明,并注册 ADR-0087 D2 转换 `hook-body-crypto-hash-removed`
(D3 挂 protocol-17):枚举值收窄不是 key 移除,故无 `retiredKey()` 墓碑,处方由
枚举 error map 按 `issue.input` 承载(`object.managedBy: 'system'` 先例)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9
…pto-hash-retire

# Conflicts:
#	docs/protocol-upgrade-guide.md
#	packages/spec/spec-changes.json
#	packages/spec/src/migrations/registry.ts
@vercel

vercel Bot commented Aug 3, 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 Aug 3, 2026 11:48am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation protocol:data tests tooling size/m labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

118 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 packages/cli, @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/cli, packages/runtime, @objectstack/spec)
  • content/docs/api/data-flow.mdx (via @objectstack/cli)
  • content/docs/api/environment-routing.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/cli, @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 packages/cli, @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/backup-restore.mdx (via @objectstack/cli)
  • content/docs/deployment/cli.mdx (via @objectstack/cli, @objectstack/spec)
  • content/docs/deployment/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/deployment/self-hosting.mdx (via @objectstack/cli)
  • 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 packages/cli, @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/cli, @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/data-service.mdx (via packages/cli)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/cli, 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/cli, @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/cli, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/cli, @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)
  • 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/cli, @objectstack/spec)
  • content/docs/protocol/kernel/realtime-protocol.mdx (via @objectstack/cli)
  • 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/cli, @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/cli, @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.

…pto-hash-retire

# Conflicts:
#	docs/protocol-upgrade-guide.md
#	packages/spec/spec-changes.json

Copy link
Copy Markdown
Contributor Author

第二次同步 main 完成(入队前)

03bc8c3dc —— 在 61cc079e 之上又并了 2 个提交(#4846/#4709app.homePageId 墓碑文案、#4861/#4775 的 hook condition fail-loud)。仍 draft,等 PM 处置。

冲突与处置:只有两个生成物冲突(spec-changes.jsonprotocol-upgrade-guide.md);conversions/registry.tsmigrations/registry.ts 本轮自动合并干净,无需人工取舍。生成物 + 四张 ratchet 一律 git checkout origin/main -- 取 main 版后整体重新生成,零文本合并。

⚠️ 本轮又撞到 #4868:merge.os-regen.driver 仍指向已删 worktree,merge 时驱动 MODULE_NOT_FOUND。按约定未顺手改,已归档在 #4868。附带一条对该单有用的观察:这次驱动崩溃后 git 把两个生成物留成了普通冲突(可见),没出现静默吞并 —— 但这是驱动"崩得响亮"的运气,不是保护生效。

逐条核对(按 PM 清单)

① 本单 D2/D3 与在飞条目并存

packages/spec/src/conversions/registry.ts : hook-body-crypto-hash-removed  ×1
packages/spec/src/migrations/registry.ts  : hook-body-crypto-hash-removed  ×1
packages/spec/spec-changes.json           : hook-body-crypto-hash-removed  ×2
docs/protocol-upgrade-guide.md            : hook-body-crypto-hash-removed  ×1

main 侧新增的 rls-sql-predicate-to-celrest-server-openapi31-block-removed 等条目均在,未被本次 merge 挤掉。

#4616 / #4657 的删除未被复活(带引号精确名,避开 EmailTemplateDefinition 家族子串)

精确名 json-schema.manifest.json api-surface.json
"system/EmailTemplate" 0 0
"system/SMSTemplate" 0 0
"system/PushNotification" 0 0
"system/InAppNotification" 0 0
"kernel/ActivationEvent" 0 0

对照组(证明 grep 有效、不是空跑):EmailTemplateDefinition 在 manifest 里仍 3 处 —— 该家族本就该留,子串扫描会误伤的正是它。

③ 四张 ratchet 相对 main 零差异(用本单自己的结论做自检)

authorable-surface.json             0 changed lines
json-schema.manifest.json           0 changed lines
api-surface.json                    0 changed lines
dual-source-exports.baseline.json   0 changed lines

同时确认改动确实在(零差异不是因为把自己的改动弄丢了):hook-body-crypto-hash-removed 在 conversions 注册表 ×1,CRYPTO_HASH_RETIRED 处方在 hook-body.zod.ts 就位。这正是正文那条「枚举值收窄对 ratchet 全部不可见」的直接复证。

重跑读数

check:generated             ✓ All 8 generated artifacts are up to date.        (8/8)
check:dual-source-exports   ✅ 4276 names / 16 entry points — 0 accepted dual-source (baseline)
check:liveness / empty-state / skill-examples / variant-docs
  / strictness-ledger / exported-any                                            全 PASS

pnpm --filter @objectstack/spec    test   →  Test Files 295 passed (295) | Tests 7365 passed (7365)
pnpm --filter @objectstack/cli     test   →  Test Files  67 passed  (67) | Tests  588 passed  (588)
pnpm --filter @objectstack/runtime test   →  Test Files  80 passed  (80) | Tests 1094 passed (1094)

turbo run typecheck (全仓)                →  Tasks: 122 successful, 122 total   exit=0
turbo run build (cli + runtime 依赖图)    →  Tasks:  54 successful,  54 total   exit=0

spec 用例数 7364 → 7365,增量来自 main 侧 #4861;本单新增的 9 条 pin(spec 4 / cli 3 / runtime 2)全绿。#4856testTimeout: 60_000 已随本次 merge 带上,今晨 5s 超时族未复现。

未 un-draft、未 auto-merge、未碰 content/docs/releases/ —— 交 PM 处置。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 3, 2026 11:49
@os-zhuang
os-zhuang enabled auto-merge August 3, 2026 11:49
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 0e96e46 Aug 3, 2026
24 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-4391-crypto-hash-retire branch August 3, 2026 12:09
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 protocol:data size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

crypto.hash 能力声明了、构建期还会自动推断,但沙箱从没实现 —— 调用直接抛(declared ≠ enforced)

2 participants