决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

Description

@os-project-manager

#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 一无所知。这是发现,不是通过。

它为什么看不见——三个各自独立、今天都还活着的原因

  1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
  2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
  3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

Activity

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

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
    Skip to content

    决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

    Description

    @os-project-manager

    #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 一无所知。这是发现,不是通过。

    它为什么看不见——三个各自独立、今天都还活着的原因

    1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
    2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
    3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

    Activity

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

    Metadata

    Metadata

    Assignees

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

      Description

      @os-project-manager

      #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 一无所知。这是发现,不是通过。

      它为什么看不见——三个各自独立、今天都还活着的原因

      1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
      2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
      3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

      Activity

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

      Metadata

      Metadata

      Assignees

      Labels

      domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

      Type

      No type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

        Description

        @os-project-manager

        #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 一无所知。这是发现,不是通过。

        它为什么看不见——三个各自独立、今天都还活着的原因

        1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
        2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
        3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

        Activity

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

        Metadata

        Metadata

        Assignees

        Labels

        domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

          Description

          @os-project-manager

          #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 一无所知。这是发现,不是通过。

          它为什么看不见——三个各自独立、今天都还活着的原因

          1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
          2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
          3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

          Activity

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

          Metadata

          Metadata

          Assignees

          Labels

          domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

          Type

          No type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

            Description

            @os-project-manager

            #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 一无所知。这是发现,不是通过。

            它为什么看不见——三个各自独立、今天都还活着的原因

            1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
            2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
            3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

            Activity

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

            Metadata

            Metadata

            Assignees

            Labels

            domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

              Description

              @os-project-manager

              #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 一无所知。这是发现,不是通过。

              它为什么看不见——三个各自独立、今天都还活着的原因

              1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
              2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
              3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

              Activity

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

              Metadata

              Metadata

              Assignees

              Labels

              domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

              Type

              No type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                决策:check-spec-symbol-derivation 要不要从符号粒度收紧到成员粒度?(实测全树 3 条悬空引用,零 allowlist) #7513

                Description

                @os-project-manager

                #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 一无所知。这是发现,不是通过。

                它为什么看不见——三个各自独立、今天都还活着的原因

                1. 规则 2 只读挂在「声明」上的注释块(attachedDoc(stmt, text))。三条断言全挂在成员上;SelectOptionMetadata 自己的 docblock 只有 /** Select option */
                2. claim 短语表要求 aligns with 真实注释写的是裸 Aligns——实测 findClaim() 对真实文本返回 null,对同一文本插入 with 后返回一条 claim。(同一文件 field-types.ts:336 写的是 Aligns with,gate 看得见——同文件里的对照。)
                3. 引用只在「符号」粒度校验,从不在「成员」粒度。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.keykey 不在该符号的 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。

                Activity

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

                Metadata

                Metadata

                Assignees

                Labels

                domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions