Filed by the domain:devx @ objectui execution seat (#5748), PM session session_012CZgmFFzqA9cX8tBMhvpFe, R34. ⛔ I do not set domain:* or type labels — routing is the triage seat's. needs-user-decision because the answer is a capability addition with a measured cost, not a fix.
⚠️This card exists because #6342's implementation returned premise_still_valid: false. The measured facts contradict the direction triage ruled, so I am filing the conflict rather than executing a ruling the measurement refutes. The hand repairs #6342 also called for are not blocked by this and ship in PR #6428.
The census that changed the question
Repo-wide, github.com/objectstack-ai/objectui/(blob|tree)/main/… occurs 138 times:
| where | count |
|---|
.md / .mdx — already in the gate's population | 117 |
outside it (.ts 18, .mjs 2, .tsx 1) | 21 |
| — of those, the gate's own deliberately-dead fixtures | 16 |
| — the literal ellipsis in the gate's own hint text | 2 |
| — genuine authored links in product source | 3 |
| — of those, already dead | 2 |
Both dead ones named MIGRATION_GUIDE.md, deleted in 8c5d20455. They are repaired by hand in PR #6428.
⭐ The finding that rules out the ruled direction
Triage's charter was "Fix is population widening in the gate: admit doc-link-bearing comments in source files."Population widening alone is a measured no-op for this defect shape.
⭐ The real mechanism: inside the gate's current markdown population, 116 of 116 self-repo blob/tree URLs are written [x](y) and 0 are bare. In source files, 3 of 3 are bare. The two populations spell links differently; the extension filter was never the only thing in the way.
Proven, not argued — a faithful simulator (same stripCode(), same regex, same self-repo arm) over a source file carrying both spellings reports the markdown one and ⛔ not the bare one, while the same simulator reports 4 findings on the gate's own fixture file, so it demonstrably works.
The noise measurement, which prices option B
Pointing the existing pipeline at 3,764 source files extracts 257 matches and would emit 194 findings — none a genuine defect:
- 135 of 194 come from the gate's own test file — a widened gate's first act is to fail on its own fixtures;
- 48 of the 257 extractions are not links at all, but TypeScript that matches the regex:
'n.title, { description: n.message }', 'msg', a regex character class, 'javascript:alert(1'.
⚠️ And the natural defence does not work here: js-comment-mask.mjs keeps comments only, while both real dead links lived in string literals. ⭐ The false-positive protection is mutually exclusive with the defect.
⛔ No baseline is proposed, and the ratchet instruction's precondition is not met: the flood is test fixtures and non-links, not historical debt. Freezing 194 fixture strings would not be a ratchet.
Options
A — Do nothing further. 2 dead links repaired by hand (PR #6428); 3 genuine self-repo URLs exist in source repo-wide, so accrual is roughly one per several thousand files. Close #6342 on the census.
B — Build the real capability. Widen the population plus a new bare-URL extractor plus a comment/string discipline. Cost: 194 findings on day one, ~135 of them the gate's own fixtures needing explicit exclusion, plus a new false-positive class — and comment-only masking would still miss the exact defect that motivated the card.
C — Narrow variant. A bare-URL-only self-repo check over source files, no markdown-link parsing at all, so none of the 194 noise. Population: the 3 genuine URLs plus the 2 in the gate's own hint text. Signal 3, noise 2, both trivially excludable.
四轴分析
① 实际业务需求. 实测债务是 2 条,已用手修完,且积累速率约为每几千个文件一条。B 为了抓一个规模为 2 的缺陷类,第一天要引入 194 条待分诊结果 —— 其中 135 条是闸门自己的 fixture。⭐ 而 B 的天然防误报手段(只保留注释)与缺陷本身互斥:两条真死链都活在字符串字面量里。这一轴强烈指向 A。
② 项目长远合理性. 北极星是 declared = enforced。⚠️ 但这里没有任何"声明"被违背 —— 闸门从未宣称覆盖源码文件,它的 SCAN_ROOTS 和扩展名过滤器都是明写的。所以 A 不制造"声明与执行不一致"。反过来,B 会让闸门开始解析源码,这是它运行时和误报面的实质改变,而不是一行正则。C 是唯一在不改变闸门性质的前提下拿到能力的形状。
③ 防 AI 写代码犯错. 这一轴是唯一支持"做点什么"的。⭐ 死链的伤害形式是:AI 读到 console.warn 里的指路,跟过去,发现文件不存在,然后自己编一个替代。本次两条正是这个形状(都指向已删除的 MIGRATION_GUIDE.md)。但规模是 2,而且 C 能以近乎零噪声拿到同样的信号 —— 裸 URL 是没有任何 TypeScript 构造会模仿的明确形状,不像 [x](y)。
④ 创业阶段不扩散需求. A 零成本。C 是一个小而明确的检查器,⚠️ 但仍是新增能力,要有人维护、要进 CI、要进 REQUIRED_CONTEXTS 的决定。B 明显超出这个阶段该花的力气 —— 194 : 2 的信噪比不是一个创业期项目该买的单。
PM 推荐:A,并把 C 作为"若确实想要这个能力"时唯一值得计价的形状
理由压在 ①④ 上:实测债务已清零,积累速率可忽略,而卡片自己的分叉规则就写着"数量小则手修"。⛔ B 是分诊设想的形状,也正是测量排除掉的那一个 —— 它以 194 : 2 的比例买信号,而它自带的误报防护恰好挡不住本次的缺陷形态。
⚠️ 若选 C,连带项要先说清:它是新增闸门,需要决定是否进 REQUIRED_CONTEXTS(本轮 #6316 刚做过一次同类判断),以及 .md/.mdx 里那 116 条裸 URL 为零的事实是否意味着两个 population 应当合并检查还是永远分开。
⛔ 推荐是输入,不是放行。
What is not blocked by this
PR #6428 (the two hand repairs) is independent and correct under all three options — the dead pointers are wrong regardless of whether a gate ever learns to see them. It is reviewed and armed separately.
Refs: #6342 (the card whose implementation produced this) · PR #6428 · #6275 / PR #6339 (the worked example the card was built on) · #6280 (the adjacent stale-surface-documentation card, landed)
Generated by Claude Code
Filed by the
domain:devx@ objectui execution seat (#5748), PM sessionsession_012CZgmFFzqA9cX8tBMhvpFe, R34. ⛔ I do not setdomain:*or type labels — routing is the triage seat's.needs-user-decisionbecause the answer is a capability addition with a measured cost, not a fix.premise_still_valid: false. The measured facts contradict the direction triage ruled, so I am filing the conflict rather than executing a ruling the measurement refutes. The hand repairs #6342 also called for are not blocked by this and ship in PR #6428.The census that changed the question
Repo-wide,
github.com/objectstack-ai/objectui/(blob|tree)/main/…occurs 138 times:.md/.mdx— already in the gate's population.ts18,.mjs2,.tsx1)Both dead ones named
MIGRATION_GUIDE.md, deleted in8c5d20455. They are repaired by hand in PR #6428.⭐ The finding that rules out the ruled direction
Triage's charter was "Fix is population widening in the gate: admit doc-link-bearing comments in source files."Population widening alone is a measured no-op for this defect shape.
MARKDOWN_LINK_RE = /\[[^\]]+\]\(([^)]+)\)/g(check-doc-links.mjs:518). ⛔ It never extracts a bare URL.console.warnstring literals — not docblocks.⭐ The real mechanism: inside the gate's current markdown population, 116 of 116 self-repo blob/tree URLs are written
[x](y)and 0 are bare. In source files, 3 of 3 are bare. The two populations spell links differently; the extension filter was never the only thing in the way.Proven, not argued — a faithful simulator (same
stripCode(), same regex, same self-repo arm) over a source file carrying both spellings reports the markdown one and ⛔ not the bare one, while the same simulator reports 4 findings on the gate's own fixture file, so it demonstrably works.The noise measurement, which prices option B
Pointing the existing pipeline at 3,764 source files extracts 257 matches and would emit 194 findings — none a genuine defect:
'n.title, { description: n.message }','msg', a regex character class,'javascript:alert(1'.js-comment-mask.mjskeeps comments only, while both real dead links lived in string literals. ⭐ The false-positive protection is mutually exclusive with the defect.⛔ No baseline is proposed, and the ratchet instruction's precondition is not met: the flood is test fixtures and non-links, not historical debt. Freezing 194 fixture strings would not be a ratchet.
Options
A — Do nothing further. 2 dead links repaired by hand (PR #6428); 3 genuine self-repo URLs exist in source repo-wide, so accrual is roughly one per several thousand files. Close #6342 on the census.
B — Build the real capability. Widen the population plus a new bare-URL extractor plus a comment/string discipline. Cost: 194 findings on day one, ~135 of them the gate's own fixtures needing explicit exclusion, plus a new false-positive class — and comment-only masking would still miss the exact defect that motivated the card.
C — Narrow variant. A bare-URL-only self-repo check over source files, no markdown-link parsing at all, so none of the 194 noise. Population: the 3 genuine URLs plus the 2 in the gate's own hint text. Signal 3, noise 2, both trivially excludable.
四轴分析
① 实际业务需求. 实测债务是 2 条,已用手修完,且积累速率约为每几千个文件一条。B 为了抓一个规模为 2 的缺陷类,第一天要引入 194 条待分诊结果 —— 其中 135 条是闸门自己的 fixture。⭐ 而 B 的天然防误报手段(只保留注释)与缺陷本身互斥:两条真死链都活在字符串字面量里。这一轴强烈指向 A。
② 项目长远合理性. 北极星是 declared = enforced。⚠️ 但这里没有任何"声明"被违背 —— 闸门从未宣称覆盖源码文件,它的
SCAN_ROOTS和扩展名过滤器都是明写的。所以 A 不制造"声明与执行不一致"。反过来,B 会让闸门开始解析源码,这是它运行时和误报面的实质改变,而不是一行正则。C 是唯一在不改变闸门性质的前提下拿到能力的形状。③ 防 AI 写代码犯错. 这一轴是唯一支持"做点什么"的。⭐ 死链的伤害形式是:AI 读到
console.warn里的指路,跟过去,发现文件不存在,然后自己编一个替代。本次两条正是这个形状(都指向已删除的MIGRATION_GUIDE.md)。但规模是 2,而且 C 能以近乎零噪声拿到同样的信号 —— 裸 URL 是没有任何 TypeScript 构造会模仿的明确形状,不像[x](y)。④ 创业阶段不扩散需求. A 零成本。C 是一个小而明确的检查器,⚠️ 但仍是新增能力,要有人维护、要进 CI、要进
REQUIRED_CONTEXTS的决定。B 明显超出这个阶段该花的力气 —— 194 : 2 的信噪比不是一个创业期项目该买的单。PM 推荐:A,并把 C 作为"若确实想要这个能力"时唯一值得计价的形状
理由压在 ①④ 上:实测债务已清零,积累速率可忽略,而卡片自己的分叉规则就写着"数量小则手修"。⛔ B 是分诊设想的形状,也正是测量排除掉的那一个 —— 它以 194 : 2 的比例买信号,而它自带的误报防护恰好挡不住本次的缺陷形态。
REQUIRED_CONTEXTS(本轮 #6316 刚做过一次同类判断),以及.md/.mdx里那 116 条裸 URL 为零的事实是否意味着两个 population 应当合并检查还是永远分开。⛔ 推荐是输入,不是放行。
What is not blocked by this
PR #6428 (the two hand repairs) is independent and correct under all three options — the dead pointers are wrong regardless of whether a gate ever learns to see them. It is reviewed and armed separately.
Refs: #6342 (the card whose implementation produced this) · PR #6428 · #6275 / PR #6339 (the worked example the card was built on) · #6280 (the adjacent stale-surface-documentation card, landed)
Generated by Claude Code