从 #7014 的执行中生出。⛔ 本席不裁,原因是先例而不是难度:这把工具的每一次加宽都先经裁定(objectui#6291),无裁而建第三次,正是它自己存在来防的那类载体缺陷。两个相关问题合并成一张卡上呈——分开呈会让维护者对同一件事裁两次。
背景:gate 看不见它本该看见的那一类
#7014 落地时(PR #7510)修掉了三条实测为假的规范断言:注释声称 @objectstack/spec声明某个键,而 spec 实际按名拒收它。逐条测过,每条都配了会点亮的对照:
SelectOptionSchema 声明键 : label, value, color, default, visibleWhen ← 无 description
option + description : REJECT unrecognized_keys keys=["description"]
CONTROL 干净 option : ACCEPT
整个 select field + option.description : REJECT unrecognized_keys at [options.0]
CONTROL 整字段干净 option : ACCEPT
FieldSchema.rows(四种多行类型) : 四者全 REJECT unrecognized_keys / 四条 no-rows 对照全 ACCEPT
FieldSchema 把 select 字段的 options 路由进那个 .strict() 的 option schema,所以在 option 上写一个 description让整个字段 422 INVALID_METADATA。那三条注释当时正在邀请这个写法。
⚠️check:spec-symbols 在这次修复前后打印逐字相同的输出(diff 验证)。三条真缺陷被移除,gate 一无所知。这是发现,不是通过。
它为什么看不见——三个各自独立、今天都还活着的原因
- 规则 2 只读挂在「声明」上的注释块(
attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */。 - claim 短语表要求
aligns with。 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。) - 引用只在「符号」粒度校验,从不在「成员」粒度。
SelectOptionSchema 是活的 spec 导出,所以悬空引用精度规则(objectui#4607)不发火,尽管 .description 根本不是它的键。
⭐ 还有第四个,更糟:卡片的假机制是从工具自己的 docblock 抄来的
#7014 说 gate 之所以瞎,是因为「both rules skip any declaration without an export modifier (hasExportModifier, applied once per scanner)」。今天这已经不成立——两半过滤器都在 #6291 被删了。独立复现:
scripts/check-spec-symbol-derivation.mjs:980 ← 声明
scripts/check-spec-symbol-derivation.mjs:143 ← docblock 散文
scripts/check-spec-symbol-derivation.mjs:164 ← docblock 散文
真调用点: 0 CONTROL(同文件同查询) attachedDoc: 2(声明 + 调用)
:1216 / :1322 // No export filter (objectui#6291).
:143 逐字描述被删掉的过滤器,:164 描述两个 scanner 会「re-run with hasExportModifier forced true」。卡片作者不是凭空编的,是读了工具自己的头注释。 这不是文档陈旧,是一份还在教下一个读者假规则的说明书。
⇒ 订正这两处 docblock 不需要裁定(是订正,不是加宽),已并入执行。下面的选项只关于要不要加宽 gate 本身。
尺寸——重新量过,卡片的旧数字是错的
#7014 用 #5899 的「47 对 18」给这件事定尺寸。⚠️ 那个数字属于已经落地的导出面加宽(#6291),不是这个洞。重测:
| 读数 | 值 |
|---|
| 成员粒度悬空引用,全树 | 3 —— #7510 修的两条 + DashboardSchema.title(已另立 #7509) |
| 原始命中 | 27 |
其中 Zod 自身方法面(.safeParse / .parse / .shape) | 22 —— 排除 |
| 需要的 allowlist 条目 | 0 |
| 规则 2 的基线漂移 | 卡片写 18 条 unbacked claim,今天跑出 19 |
三条,不是三十条。零 allowlist,恰好是这把 guard 自己头注释立的标准:「an ALLOW map with 38 entries is not a guard」。
选项
A —— 只加成员粒度引用检查。 注释引用 SpecSymbol.key 而 key 不在该符号的 shape 里时报错。这是把已有的精度规则 4 从符号粒度收紧到成员粒度,不是第二把工具。
B —— 同时把规则 2 加宽到读成员挂载的注释,而不只是声明挂载的。⚠️ 这是另一个总体:57 份成员 doc 带 claim 短语。dev 与本席同判——该单独测量后再裁,不应搭在 A 上。
C —— 都不做,继续一卡一卡地订正站点。
A′ —— 先 A,B 欠一次测量再议。 (dev 的推荐,也是本席的倾向。)
附问:裸 aligns 要不要进短语表?
规则 2 的短语表要求 aligns with,真实注释常写裸 Aligns——这正是 SelectOptionMetadata 那条连规则 2 本可触及的部分都没看见的原因。
- a:把裸
aligns/aligned 加进 CLAIM_PATTERNS。 - b:不动,短语表是刻意廉价的。
dev 推荐 b 暂不动,但欠一次测量,本席同意并把理由记下:在一个已经产出 19 条 unbacked claim 的启发式上加一个高频裸动词,假阳性面没量过就不该裁——dev 明确说了它没量,而不是量了很小。这条测量便宜,谁先动这张卡谁顺手跑。
本席倾向:A′ + b(欠测量)
理由:(a) 真实需求——3 条实测悬空引用,其中两条正在邀请 422;(b) 长期健全——A 是收紧既有规则的粒度,不新增工具面;(c) AI 不易做错——把「引用一个不存在的成员」变成红,正是本轮三条假断言的成因;(d) 创业期尺度——零 allowlist、三个站点,而 B 的 57 份成员 doc 是没量过的总体。
⛔ 但先例说了算:#6291 是先裁后建的。请裁。
派工状态
⛔ needs-user-decision,不带pm:queue——本卡在裁定前不进队列(#6853 点名的缺陷:卡片自己说不可派工而标签仍在招手)。
不受本卡阻塞:PR #7510(已落确定的一半,Clause-② no);#7509(DashboardSchema.title,第三条悬空引用);#7014 仍开,余下 Q1(Tier-1 收敛)与 Q2(patchOptions 守卫)已由本席裁明,见 #7014 评论 5528139486。
从 #7014 的执行中生出。⛔ 本席不裁,原因是先例而不是难度:这把工具的每一次加宽都先经裁定(objectui#6291),无裁而建第三次,正是它自己存在来防的那类载体缺陷。两个相关问题合并成一张卡上呈——分开呈会让维护者对同一件事裁两次。
背景:gate 看不见它本该看见的那一类
#7014 落地时(PR #7510)修掉了三条实测为假的规范断言:注释声称
@objectstack/spec声明某个键,而 spec 实际按名拒收它。逐条测过,每条都配了会点亮的对照:FieldSchema把 select 字段的options路由进那个.strict()的 option schema,所以在 option 上写一个description让整个字段 422INVALID_METADATA。那三条注释当时正在邀请这个写法。check:spec-symbols在这次修复前后打印逐字相同的输出(diff 验证)。三条真缺陷被移除,gate 一无所知。这是发现,不是通过。它为什么看不见——三个各自独立、今天都还活着的原因
attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata自己的 docblock 只有/** Select option */。aligns with。 真实注释写的是裸Aligns——实测findClaim()对真实文本返回null,对同一文本插入with后返回一条 claim。(同一文件field-types.ts:336写的是Aligns with,gate 看得见——同文件里的对照。)SelectOptionSchema是活的 spec 导出,所以悬空引用精度规则(objectui#4607)不发火,尽管.description根本不是它的键。⭐ 还有第四个,更糟:卡片的假机制是从工具自己的 docblock 抄来的
#7014 说 gate 之所以瞎,是因为「both rules skip any declaration without an
exportmodifier (hasExportModifier, applied once per scanner)」。今天这已经不成立——两半过滤器都在 #6291 被删了。独立复现::143逐字描述被删掉的过滤器,:164描述两个 scanner 会「re-run withhasExportModifierforced true」。卡片作者不是凭空编的,是读了工具自己的头注释。 这不是文档陈旧,是一份还在教下一个读者假规则的说明书。⇒ 订正这两处 docblock 不需要裁定(是订正,不是加宽),已并入执行。下面的选项只关于要不要加宽 gate 本身。
尺寸——重新量过,卡片的旧数字是错的
#7014 用 #5899 的「47 对 18」给这件事定尺寸。⚠️ 那个数字属于已经落地的导出面加宽(#6291),不是这个洞。重测:
DashboardSchema.title(已另立 #7509).safeParse/.parse/.shape)三条,不是三十条。零 allowlist,恰好是这把 guard 自己头注释立的标准:「an ALLOW map with 38 entries is not a guard」。
选项
A —— 只加成员粒度引用检查。 注释引用
SpecSymbol.key而key不在该符号的 shape 里时报错。这是把已有的精度规则 4 从符号粒度收紧到成员粒度,不是第二把工具。B —— 同时把规则 2 加宽到读成员挂载的注释,而不只是声明挂载的。⚠️ 这是另一个总体:57 份成员 doc 带 claim 短语。dev 与本席同判——该单独测量后再裁,不应搭在 A 上。
C —— 都不做,继续一卡一卡地订正站点。
A′ —— 先 A,B 欠一次测量再议。 (dev 的推荐,也是本席的倾向。)
附问:裸
aligns要不要进短语表?规则 2 的短语表要求
aligns with,真实注释常写裸Aligns——这正是SelectOptionMetadata那条连规则 2 本可触及的部分都没看见的原因。aligns/aligned加进CLAIM_PATTERNS。dev 推荐 b 暂不动,但欠一次测量,本席同意并把理由记下:在一个已经产出 19 条 unbacked claim 的启发式上加一个高频裸动词,假阳性面没量过就不该裁——dev 明确说了它没量,而不是量了很小。这条测量便宜,谁先动这张卡谁顺手跑。
本席倾向:A′ + b(欠测量)
理由:(a) 真实需求——3 条实测悬空引用,其中两条正在邀请 422;(b) 长期健全——A 是收紧既有规则的粒度,不新增工具面;(c) AI 不易做错——把「引用一个不存在的成员」变成红,正是本轮三条假断言的成因;(d) 创业期尺度——零 allowlist、三个站点,而 B 的 57 份成员 doc 是没量过的总体。
⛔ 但先例说了算:#6291 是先裁后建的。请裁。
派工状态
⛔
needs-user-decision,不带pm:queue——本卡在裁定前不进队列(#6853 点名的缺陷:卡片自己说不可派工而标签仍在招手)。不受本卡阻塞:PR #7510(已落确定的一半,Clause-② no);#7509(
DashboardSchema.title,第三条悬空引用);#7014 仍开,余下 Q1(Tier-1 收敛)与 Q2(patchOptions守卫)已由本席裁明,见 #7014 评论 5528139486。