Repository navigation
zod bump (#19581 / PR #19658): the version that fixes the crash is the same version that breaks the view-authoring diagnosis — decide the landing order #19674
Description
Ruled: 5774631464 · letter A · 2026-09-22T10:05Z — batch #212 item 1, maintainer 「19674 反正要升级,建议一步该到位」; closed completed, execution rides #19581 / PR #19658
维护者速读
把 zod 升到修好崩溃的那一版,会让 AI 作者在改视图配置被拒时,收到的提示从「你用的 page 这个值已经被移除了」变成「请把你的内容包进一个容器里」。后者是错的,照做只会更错。
原本指望能绕开:换一个只带修复、不带这个副作用的版本。已穷尽实测 12 个已发布版本,不存在 —— 厂商把两件事放在同一次发布里(4.5.0)。所以只剩一个问题:先升级还是先修提示。
顺带一条:这张卡的裁决把修复版本写成 4.6.1,实测是 4.5.0,早五个版本。不影响已提的 PR(它的下限更高,只是没必要那么高),但裁决原文需要更正。
推荐 C:先修提示层,再把升级叠上去。请回一个字母:A / B / C。
一句话问题
用 AI 写视图配置的人,今天写错一个已被移除的取值时会收到一句点名该取值的拒绝;升级依赖之后,同一个错误换来一句把他引向错误改法的拒绝。
Governing text
- 本卡裁决
5770530634,letter B —— 「Bumpszodto the fixed line … as its own dependency PR, with a regression pin」。⚠️ 该裁决内含两条实测不成立的前提,见下。 Prior rulings read: invalid_union,union diagnostics,zod bump,retirement prescription,view container → 0 hits; none; thread: none; repo: objectstack-ai/objectstack- ⛔ 协议本身不改:三个选项都不改任何已声明的 schema 形状,动的只是被拒时的提示文本与落地顺序。
裁决前提的两处更正,都是实测
- 修复落在 4.5.0,不是裁决写的 4.6.1。 穷尽扫过 4.4.3 到 4.6.5 共 12 个已发布稳定版:formatter 的九项结果在 4.4.3 是 8 坏,在 4.5.0 起全部干净。源码佐证:
v4/core/errors.js里function node(obj, key, make)与三处Object.prototype.hasOwnProperty.call,4.4.3 为 0,4.5.0 与 4.6.1 逐字相同。 - 「every workspace range is
^4.4.3」在一处不成立 ——apps/docs是精确钉死的4.4.3,不接受修复版。13 个声明处只有它是例外,也正是它把这件事从「只改 lockfile」变成需要改声明。
⇒ 由此派生一个附带问题:PR 现在声明的下限是 ^4.6.1(裁决点名的线),实测最低只需 ^4.5.0。两者都在修复之上,所以 PR 没有错;要不要收到实测最小值,请在回信里一并说,dev 已明确不自行改动。
选项 × 真实代价表
| 做什么 | 客户可感知的后果 | |
|---|---|---|
| A | 同一个 PR 里升级,并把视图诊断层一起修好 | 提示始终正确;但一次依赖升级变成一个横跨四个包的改动,出问题时无法单独回滚升级 |
| B | 先升级,接受提示退化,另立单跟进 | 从今天起到跟进单落地为止,每个用 AI 改视图的人拿到的都是错误改法;窗口期无机制保证关闭 |
| C | 先修视图诊断层,再把升级 rebase 上去 | 崩溃修复晚到一个回合;提示从头到尾正确;升级保持单提交可回滚 |
| D | 换一个只带修复不带退化的版本 | ⛔ 已穷尽实测,不存在。修复与退化同在 4.5.0 —— 本项已关闭 |
实测补充,决定 B 的代价有多重:崩溃在本仓零调用点(亮控:同命令同半径下 safeParse 命中 627 个文件)。也就是说,崩溃伤的是下游消费者格式化本平台抛出的拒绝时,本仓自己碰不到;而提示退化伤的是每一个改视图的作者,天天碰。⇒ 「先升级止血」的直觉在这里不成立:本仓没有在流血。
业务含义直译
- A = 把「换掉一个有毛病的零件」和「重写产品的错误提示」写进同一张工单。两件事以后要分开追溯就没得追。
- B = 明知说明书这一页印错了,先把货发出去,承诺以后补一张勘误。补不补得上,没人担保。
- C = 先把说明书印对,再换零件。换零件晚一天,但没有任何一天是拿错说明书在指导客户。
四轴,从业务立场
① 项目长远合理性。 C 不新增任何特例:两件事各自保持可单独回滚,升级仍是它本该是的一行依赖变更。B 反向——它引入一个「已知错误提示」的临时状态,而临时状态没有到期机制就是永久状态。A 把一次零件更换和一次公开文案修改绑成一个不可分割的提交,以后任何一方出事都得连坐回滚。⇒ C
② 实际业务拉动。 今天谁撞上:提示退化是每个用 AI 改视图配置的人,每次改错都撞;崩溃在本仓无人撞(零调用点,亮控 627),撞的是下游消费者。两者都真实,但一个是天天,一个是本仓碰不到。⇒ 拉动更强的一侧要求提示不能先坏,即 C
③ 防 AI 犯错。 本轴要的是「闭合枚举优于自由结构,响亮拒绝优于静默容忍」。三个选项都保住了「响亮拒绝」——没有任何一个会让错误配置静默通过。差别在拒绝说了什么:今天说「page 这个取值已被移除」,这是闭合枚举的正确出口;B 之后说「请把内容包进一个容器」,作者照做,运行时会兑现这个改法,然后事情更糟。⇒ 一个会被兑现却把人引向更坏结果的拒绝,是本轴最差的一格,比静默还难查,因为作者有理由相信它。B 在本轴出局。⇒ C
④ 创业阶段不扩散。 remove 优于 declare-and-maintain。C 不新增任何声明。B 新增一条没写进任何地方的隐性义务(「记得回来修提示」),而每条未声明的义务都会被下一轮遗忘。A 不新增声明,但把公开文案的修改埋进一个依赖升级里,等于声明了一件没人会去读的事。⇒ C
推荐 + 回退 + 置信缺口
推荐:C。 回退项:B,且仅在崩溃对某个已知下游消费者正在造成实际损失时才回退到它 —— 那会翻转②,而②是唯一可能翻转本推荐的轴。
自检行:只看①选 C;②③④ 是否翻转:否。
置信缺口,明说看不见什么:
- ⛔ 退化的机制尚未定位。 dev 已逐一证伪三个假设(通用 union 聚合变化、preprocess/check 包装、lazySchema Proxy 成员),三者在两个版本上表现完全一致。剩余候选收窄到视图成员自身的 strictObject/superRefine、
z.never墓碑、或assertViewIdentity前置门。⇒ 修复成本未知,C 的「晚一个回合」可能不止一个回合。这是 C 最大的不确定处,也是唯一能把 B 拉回来的理由。 - ⛔ 退化的广度是下界不是全量。 目前测到 78 处断言、17 个文件、至少三个测试分片;其中一个分片报告 12 个计划包有 11 个从未跑到。真实面只会更大。
- ⛔ 本席未独立复现那条门口读数,采信的是 dev 的双工作树、同源字节一致的对照。at-tier 复核会重新推导,⛔ 不沿用。
裁后执行段
- 回 C ⇒ 本席立视图诊断修复单(附 dev 已证伪的三个假设,免得重跑),派发;修复落地后把 fix(deps): bump zod to the fixed line (4.6.1+) workspace-wide, with a regression pin #19658 rebase 上去,重取 at-tier 复核,再走四项落地前提。fix(deps): bump zod to the fixed line (4.6.1+) workspace-wide, with a regression pin #19658 期间保持 draft。
- 回 B ⇒ fix(deps): bump zod to the fixed line (4.6.1+) workspace-wide, with a regression pin #19658 按现状走 at-tier 复核并落地,同笔立跟进单并挂上到期判据;⛔ 本席会要求那张单带一条可执行的关闭条件,不接受「以后修」。
- 回 A ⇒ 本席退回 dev 扩面重做,PR 正文申报全部越界文件面;
⚠️ 这条会让一个已经 20 文件的 PR 再横跨四个包,at-tier 复核成本最高。 - 三者皆同:裁决原文的 4.6.1 更正为 4.5.0 由本席在本卡记录;声明下限取
^4.5.0还是留^4.6.1,按你回信执行,⛔ 不默认。
os-decision-facets
- ① 项目长远合理性:C 不新增特例,两件事各自可回滚;B 引入无到期机制的临时错误状态,A 把依赖更换与公开文案修改绑成不可分割的一笔。
- ② 实际业务拉动:提示退化每个改视图的作者天天撞;崩溃在本仓零调用点(亮控 627 文件 safeParse),撞的是下游消费者 —— 拉动更强的一侧要求提示不先坏。
- ③ 防 AI 犯错:三者都保住响亮拒绝,但 B 之后的拒绝会把作者引向一个运行时会兑现却更糟的改法,是本轴最差一格,比静默更难查。
- ④ 创业阶段不扩散:C 零新增声明;B 新增一条没写进任何地方的隐性义务;A 把公开文案改动埋进依赖升级。
Prior rulings read: invalid_union,union diagnostics,zod bump,retirement prescription,view container → 0 hits; none; thread: none; repo: objectstack-ai/objectstack
推荐 C。自检:只看①选 C;②③④ 是否翻转:否。置信缺口:退化机制未定位 ⇒ 修复成本未知,这是唯一能把 B 拉回来的理由;退化广度是下界,非全量。
相关单与 PR
- 卡 [rebuild of #19421] [finding] zod 4.4.3's
treeifyErroranderror.format()throw on any issue path containing__proto__— so the formatter crashes on exactly the refusal PR #19147 landed to make that key safe #19581 · PR fix(deps): bump zod to the fixed line (4.6.1+) workspace-wide, with a regression pin #19658(draft,红在至少三个Test Core分片,⛔ 未改任何测试) - 本卡由
domain:spec执行席 2 于 2026-09-22T06:2xZ 立,sessionsession_01UDXER3sdqfeVYpEWZs5mZx - 查重词:
zod 4.5.0 formatter fix、ruling 5770530634 version premise、invalid_union prescription lost、view container unrecognized keys、treeifyError hasOwnProperty release
Generated by Claude Code
Activity
os-support-ai commentedon Sep 22, 2026
Ruling: batch #212 item 1 · letter A · maintainer 「19674 反正要升级,建议一步该到位」 · 2026-09-22T10:05Z
Director seat, summon #27,
session_0129ZpnaBcYZZ51rCvQiXg6C. The maintainer's words name no letter; read as A (one PR: the zod bump AND the view-diagnosis repair, one step to done), against the seat's C recommendation. Recorded verbatim; the seat's C stays on the card as history.Ruled shape — complete at ruling time, ⛔ no further decision card for the dev.
page) is refused by a message that NAMES the retired value, as today — ⛔ never the 「wrap your content in a container」 prescription. ⛔ No test is rewritten to accept the degraded message; the 78 assertions across 17 files (a lower bound) turn green by repairing the diagnosis layer, not by editing what they assert.z.nevertombstones, theassertViewIdentitypre-gate) are measured on both zod versions with the same lit control. The mechanism found and the fix are written into the PR body with the reading.Clause-②: yeson the claim (re-declared from the delivered diff), at-tier contract review before landing; ⛔ not a return to the box.^4.6.1as the PR already has it (above the measured fix at 4.5.0; harmless, and one fewer round under 「一步到位」);apps/docs's exact4.4.3moves to the same range so the workspace resolves one version; lockfile regenerated bypnpm, ⛔ never hand-edited.treeifyErroranderror.format()throw on any issue path containing__proto__— so the formatter crashes on exactly the refusal PR #19147 landed to make that key safe #19581 said the fix is 4.6.1; the card's exhaustive scan puts it at 4.5.0 — amended on [rebuild of #19421] [finding] zod 4.4.3'streeifyErroranderror.format()throw on any issue path containing__proto__— so the formatter crashes on exactly the refusal PR #19147 landed to make that key safe #19581 in this stroke.every workspace range is ^4.4.3was false forapps/docs— same amendment.package.json+ lockfile (the four packages the card names), as a scope widening under this ruling, quoting the maintainer's words;Fixes #19581; changeset level per the dev's delivered diff (a diagnosis-text repair insidepackages/specis at least a patch on@objectstack/spec).domain:specseat 2 (assigneeos-warren, sessionsession_01UDXER3sdqfeVYpEWZs5mZx) continues on [rebuild of #19421] [finding] zod 4.4.3'streeifyErroranderror.format()throw on any issue path containing__proto__— so the formatter crashes on exactly the refusal PR #19147 landed to make that key safe #19581 with a patch round on PR fix(deps): bump zod to the fixed line (4.6.1+) workspace-wide, with a regression pin #19658 under this widened scope — ⛔ not a new card, ⛔ not a re-dispatch from the queue. Pointer left on [rebuild of #19421] [finding] zod 4.4.3'streeifyErroranderror.format()throw on any issue path containing__proto__— so the formatter crashes on exactly the refusal PR #19147 landed to make that key safe #19581.Prior rulings read: 5770530634 (class-1, #19581, letter B — upheld in direction, amended on the version premise); ruling A-narrow 5725370319 on #17852 (no
__proto__sweep — untouched); ADR-0059 §3, ADR-0005 §3, ADR-0032 §1, ADR-0059 §5, ADR-0076 D9, ADR-0081 §3 (the prior-rulings scan's broad-term hits; none rules on a dependency bump's landing order); thread: none.State in this stroke.
needs-user-decisionremoved; the card closedcompleted(the decision is made; execution rides #19581 / PR #19658). Body first line gainsRuled: <this comment's id> · letter A · <UTC>.Generated by Claude Code