Repository navigation
Closed
Labels
bugSomething isn't workingSomething isn't workingdomain:devxDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
Description
#5017 的全包 grep 顺带发现的第八处,落在第三个文件,不在 #5017(validate-expressions.ts / validate-security-posture.ts)的处置范围内,按 Prime Directive #10 单独记账。
事实
packages/lint/src/validate-rule-compilability.ts:239:
// `validations` is the spec key; `validationRules` is read for the same
// …
const validations = obj.validations ?? obj.validationRules;ObjectSchema.shape 只声明 validations,且是 strict —— 实测:
objects[].validationRules parses? false
["objects.0: Unrecognized key(s) on this object: `validationRules`. …
Did you mean `validationRules` → `validations`?"]
validateRuleCompilability 也是 input: 'parsed' 注册的规则,所以在 compile 路径上 obj.validationRules 恒为 undefined。canonical 排首位,别名 limb 不可达 —— 和 #5009 那四条、#5017 前六条完全同形。
与 #5017 的关系
#5017 已在另外两个文件把同族的七条收敛完毕(PR #5046),并落了两层结构性 meta-guard(declared-key ⊆ schema.shape + reachability)。这一条没有一并改,是因为:
- 它在第三个文件,validate-expressions / validate-security-posture 也有同形的 spec 不声明键的
??别名读法(#5009 建议 3 的核对结果) #5017 的议题正文和验收条件都没有点名它; - fix(lint): 收敛 validate-expressions / validate-security-posture 的 spec 不声明键
??别名读法 (#5017) #5046 的真实元数据零新红、反向验证、变异测试都是围绕那两个文件做的,顺手带上第三个规则等于把没做过同等验证的改动混进已经绿了的 PR; - 它自己那份 meta-guard 需要单独写(该规则的 finding 形状与两者又不同)。
处置建议
照 #5046 的模式办:
- 收敛为
obj.validations; - 补 declared-key guard(该规则从
obj/ 规则对象上读的每个键 ⊆ 对应.shape)+ reachability guard; - 反向验证注意方向:canonical 排首位,所以改动前对非法拼法越权判红,改动后让位给 schema 的具名拒绝 —— 与 fix(lint): 删除 validateOrgAxisRedLines 里 spec 合法 stack 到不了的四条分支 (#5009) #5018 的方向一致;
- 现有 fixture
validate-rule-compilability.test.ts:295用的正是validationRules:拼法,改动时要一并改成 canonical(否则该用例会静默失去覆盖 —— fix(lint): 收敛 validate-expressions / validate-security-posture 的 spec 不声明键??别名读法 (#5017) #5046 在runtime-gate.test.ts上正好踩到这个:别名拼法让"上下文里有坏规则"的 fixture 实际上一条 finding 都产生不了,断言toEqual([])通过的原因是没有东西可减而不是减法正确)。
理由两条轴,与 #5017 同:
- 长期正确性:consumer 容忍 producer 明确拒绝的别名,是把一条具名拒绝降级成静默失效的分支;读代码的人(和照着写的 AI)会相信
objects[].validationRules是真实的 authoring 面。 - 让 AI 写的元数据难写错:别名容忍属于 producer 的拒绝面,不属于 consumer(Prime Directive Add comprehensive test suite for Zod schema validation #12)。
参考
- validateOrgAxisRedLines 读的 sharing-rule 键是 spec 拒收的:ADR-0105 D6 ① 在 criteria 路径上从不触发 #4984 / validateOrgAxisRedLines 仍留着三条 spec 合法 stack 到不了的别名分支(objects[].rowLevelSecurity / .rls / permissionSets)—— #4984 修了 sharing 那一半 #5009 / validate-expressions / validate-security-posture 也有同形的 spec 不声明键的
??别名读法(#5009 建议 3 的核对结果) #5017 / PR fix(lint): 收敛 validate-expressions / validate-security-posture 的 spec 不声明键??别名读法 (#5017) #5046(同族前三轮)、validate-expressions.ts 的 field-formula 校验读f.formula—— spec 声明的是expression,这段从未对任何 spec 合法 stack 跑过 #5026(同族但非??链的f.formula)、未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001(strict + 别名按名拒绝)
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingdomain:devxDomain lane — seat card indexed by label:pm:seatDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
Activity
fix(cli,lint): 把消费被拒别名拼法的 fixture 改为 canonical (#5017)
xuyushun441-sys commentedon Aug 4, 2026
认领(PM 分派)
session_018iARDqtrhQgz6fVHDeDkbQclaude/issue-5096-rule-compilability-aliasdomain:devx(落点packages/lint/src/validate-rule-compilability.ts+ 其测试;与在飞 validate-expressions.ts 的 field-formula 校验读f.formula—— spec 声明的是expression,这段从未对任何 spec 合法 stack 跑过 #5026 的validate-expressions.ts同包不同文件,互斥)按本单自带的 playbook 执行(#5046 沉淀的),特别是:
validate-rule-compilability.test.ts:295的validationRules:fixture 必须一并换 canonical —— runtime-gate 刚示范过"绿但空转"的陷阱。Generated by Claude Code
xuyushun441-sys commentedon Aug 4, 2026
审核通过 — PR #5121 已取消草稿并挂上 auto-merge(SQUASH);同族第 8 例收官
:295fixture 的实测方向与议题预警相反,处置因此更对:不是 runtime-gate 那种 0→N(空转断言终于干活),而是 1→0 —— 该测试主动钉着被删的别名 limb,真的在触发。所以不能换拼写保绿(那会留下一个测试主题已不存在的绿测试),必须替换:新测试钉 schema 的具名拒绝文案 + canonical 1 条 vs 别名 0 条 + 重建OLD_CHAIN证明新旧读法只在 schema 已拒的输入类上有差。先测量再动手,这是三种 fixture 处置(re-spell / 补声明 / 替换)里第三种的首个实例,进方法论。guard 比 #5046 更严一档且理由讲清了:reachability 用全量 safeParse(#5018 原始 bar)—— 因为 zod 把
regex当任意字符串、schema当任意 record,不可编译的产物本身就是 spec 合法的,这条规则存在的理由恰是 zod 看不见这类缺陷,所以永远不需要 zod 拒收的 fixture。与 #5046 在 security-posture 上放宽到unrecognized_keys的理由互为镜像 —— 判据跟着规则的性质走,不是模板。另有两处细活:字符串字面量剥离(finding 里的 config path 模板会让朴素 dotted 扫描逼出装饰性豁免)、rule[branch]计算键的专项断言(dotted 扫描的盲区,恰是本规则最要紧的读法)。全文件仅此一条链,无新同族;真实元数据 28 对象 / 17 规则 diff 逐字为空;M1/M2 变异 2/11 红;lint 1172 测试、cli 消费半径 37 测试全绿。落点 3 文件,未碰在飞 #5026 的文件。
Generated by Claude Code
fix(lint): 收敛 validate-expressions / validate-security-posture 的 spec…
fix(lint): 收敛 validate-rule-compilability 的 spec 不声明键 `??` 别名读法 (obje…