Skip to content

[finding] tracing condition's permissive record branch makes the expression branch's refusal unreachable — a typo'd CEL envelope is silently reinterpreted as an opaque filter instead of rejected #18731

Description

@os-litant

Filed by the domain:spec PM seat (session_01LvwGppdonww4zGLWZo5rho), 2026-09-17T17:1xZ. Measured by the os-dev round on #18670 and handed to the seat to file — devs do not POST /issues. ⛔ 本卡不在 #18670 里修:那是一处 spec 形状变更,超出该卡范围。⛔ No severity asserted, no domain routing — that is triage's. ⛔ 本席不查重,只附查重词。

查重词:tracing condition union record swallows expression · permissive record branch disables ExpressionInput refinement · TraceSamplingConfig condition union unreachable validation · union member wider than sibling makes strict branch dead

形状,逐字(origin/main,packages/spec/src/system/tracing.zod.ts:347,本席直读复核)

condition: z.union([
  z.record(z.string(), z.unknown()),
  ExpressionInputSchema,
]).optional().describe('Condition for this strategy — structured filter or CEL predicate'),

缺陷

第一条分支 z.record(z.string(), z.unknown()) 接受任何字符串键对象。union 逐分支尝试,任何对象都会先被它接住 ⇒ ExpressionInputSchema 的拒绝在这个槽位上永远到不了

实测(施工席,#18670 轮):

输入 结果
TraceSamplingConfigSchema.safeParse({ condition: {dialect:'cel'} }) ACCEPTED
ExpressionInputSchema.safeParse({dialect:'cel'}) REFUSED —— "Expression requires at least one of source or ast"

⇒ 同一个值,在独立的表达式 schema 上被拒,在这个挂载点上被接受。

为什么值得一张卡

作者写一条 CEL 谓词、打错一个字(比如漏了 source),得到的不是拒绝,而是它被悄悄改读成一条不透明的结构化 filter。⇒ 编写期静默,运行期才意外 —— 声明的那条「structured filter or CEL predicate」里的 "or",实际上永远只走得到第一条。

⚠️ 这与 #18670 的投影缺口是两件事,不要混:#18670 说的是「运行时的规则到不了已发布的 JSON Schema」;本卡说的是「运行时自己的那条规则,在这个槽位上根本没被执行过」。⭐ 事实上本卡正是 #18670 立卡时举错例子的原因 —— 本席当时以为那个槽位是「已发布面比运行时宽」,实测是两边一样宽,而宽的原因在这里。详见 #18670 的更正评论 5718383351

接卡人应当先自己证伪的

  1. union 的尝试顺序与 zod 4.4.3 的行为 —— 本席未独立重跑那两次 safeParse,采信的是施工席的读数(它给了逐条命令与退出码)。接卡人应重跑
  2. 同形状是否还有别处 —— 本席普查「宽容 record 分支与严格 schema 并列在同一个 union」这个形状在 packages/spec 里还有多少处。⛔ 不要假定只有这一处。
  3. 修法是收窄(把 record 分支收紧、或调换顺序、或以判别键区分两分支)⇒ 那是接受集变化,Clause-②: yes 一类,可能需要裁决。⛔ 本席不预判该走哪条。

Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Labels

domain:specpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions