You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-timeline): non-string gantt dates that coerce to the epoch (0, false, []) still draw a 649-column 1970 axis with no diagnostic #6781
Filed unassigned while implementing objectui#6770 (the null gantt date). Deliberately left out of that card — see "why this is not the same input class" below.
Measured on c6732825d with a throwaway probe, one row item, i.e. with objectui#6759's guards in the tree and before objectui#6770's change:
Identical, byte for byte, to the reading objectui#6770 was filed for. new Date(0), new Date(false) and new Date([]) are all the epoch, so every one of them passes the parse guard and anchors the axis in 1970 with no error, no diagnostic and no console warning.
Why this is NOT the same input class as objectui#6770
objectui#6770 refuses null on the ground that null is an absence spelling — what a record mapping hands you for an unset field — which objectui#6759 already refuses when it is spelled undefined. Its guard is value === null and deliberately nothing wider, because:
0 is a legitimate epoch timestamp. startDate: 1704067200000 renders 2024 correctly today, and there is no way to tell 0 apart from an author who genuinely means 1970-01-01.
false / [] are neither timestamps nor absence spellings; refusing them means a type rule ("a gantt date must be a string, a number or a Date"), which is wider than any of the three cards so far and would have to be adjudicated as such.
So this is a policy question, not a mechanical fix, and it is a different question from the one objectui#6770 answered.
The three arms, as they look from here
A type rule. Refuse anything that is not a string, a finite number or a Date. Catches false / [] / {} and leaves 0 rendering as 1970 — which is arguably correct, since 0 really is a date in that encoding.
Refuse 0 too, on the ground that a 0 in a date field is almost always an unset integer column rather than an author meaning 1970. Costs the ability to author the epoch, which nobody plausibly wants but which is currently legal.
Leave it.false / [] in a date field are not plausible authored input, and 0 is genuinely ambiguous. The 1970 axis stays reachable through a door narrower than the one objectui#6770 closed.
Where it lives
packages/plugin-timeline/src/renderer.tsx — findUnusableGanttDate, the isUnusable predicate. Line numbers deliberately omitted: re-derive them on your base.
needs:contract-review removed — 执行维护者 2026-08-28 对 objectstack#12887 的裁定(可复审增量存在前永不挂标;预挂已废止)。本卡 dev 在飞、PR 尚未存在,条款② 判定不变(裁决已言明「预期 yes」),PR 存在的同笔即重挂双载体。⛔ Deliberate removal, not a sanitizer strip — do not re-hang without a reviewable diff. 项目总监席,session session_01DxbNgzPMo4YuRBmGmCQp9m。
Activity
claude commentedon Aug 29, 2026
状态更正 —— 本席自纠:
pm:queue→needs-user-decision本卡由本席(
domain:ui执行席)填,当时打了pm:queue。那是错的:卡的正文自己写着「这是一个政策问题,不是一次机械修复」,并列了三条互斥的臂。带pm:queue的卡对派发查询说「可以派」,而这张卡派下去只能让 dev 替维护者选一条臂 —— 标签就是状态机,它必须诚实。改挂⚠️
needs-user-decision,补四棱块。priority:p1是立卡时随手继承的,没有重新判过;结合下面第②轴(零实测拉动),它值得分诊席重读一次,本席不自行改定级。一句话问题:gantt 日期字段里
0、false、[]全部通过解析守卫 —— 三者的new Date(…)都是纪元 —— 把时间轴锚在 1970(实测 649 个月桶、left: 100%; width: -100%;),零报错、零诊断、零 console 警告。#6770 只裁了null,理由是null是「缺失」的拼写;本卡是它明确留下的余量。三条臂
Date一律拒绝false/[]/{};0照旧渲染 1970 —— 而这可以说是对的,0在该编码里真的是一个日期0一起拒0几乎总是未设值的整数列。代价:拿走合法的纪元,那是今天合法的作者面false/[]不是可信的作者输入,0真的有歧义。1970 轴仍可达,但门比 #6770 关掉的那扇窄四棱
① 长远合理性:A 是契约面的一句话——「gantt 日期必须是字符串、有限数字或⚠️ 实测为零。 没有任何记录显示作者真的写过
Date」。它比 #6770 的value === null绝对地宽,是一条新的公开接受集规则,应当被当作规则明写下来,而不是从一次缺陷修复里长出来。② 业务拉动:
false/[]。0有可信来源(未设值的整数列),但同样没有实测到。⇒ 三条臂里没有一条压在已观察到的用户损伤上。③ 防 AI 犯错:⭐ 分水岭在这里。「未设值的整数列产出
0」正是机器映射最容易产生的形状,而它今天静默渲染 1970 —— 静默正是错值的藏身处。但 B 同时拿走合法纪元,⇒ 这一轴指向 A 或 B,不指向 C。④ 不扩散:C 零成本;A 是一条有界的类型规则;B 改变已发布的接受集,是三者里唯一的破坏性变更。
⭐ 置信缺口(本席未测,诚实列出)
0喂进 gantt 日期的站点。这个数字直接决定 B 值不值 —— 为 0 则 B 是在为假想输入拿走合法能力。false/[]能否由 SDUI 作者面产生,还是只有手写 TS 调用才到得了。若 schema 校验已挡在前面,A 的收益只落在手写调用面上,量级完全不同。nullgantt date is silently coerced to the epoch — a 649-column axis and a negative-width bar, with no diagnostic #6770 的裁决措辞是否已经隐含把接受集限制为「absence 拼写」。若是,A 就不是新规则而是把既有裁决写全,①轴的分量下降一档。低摩擦裁决:回「A」「B」或「C」。
裁后执行:裁 A 或 B ⇒ 转
pm:queue,落点是packages/plugin-timeline/src/renderer.tsx的findUnusableGanttDate/isUnusable谓词(#6782 已于 2026-08-29T14:11:51Z 合并进同一文件,以合并后的 ref 重新定位行号)。裁 C ⇒ 关 not planned,并把「0渲染为 1970」写进该谓词旁的注释、指向本卡 —— ⛔ 不可只关不写,那正是本卡记录的静默。Generated by Claude Code
zhuangjianguo commentedon Aug 30, 2026
⚖️ RULED — 维护者,2026-08-30,第 5 场总监席决裁批 #6,verbatim「其他同意」(采本席推荐)
裁定:采选项 A(类型规则) —— gantt 日期必须是 string、有限 number 或
Date;其余类型(false/[]/{}等)拒绝并走 #6759/#6770 既有的响亮诊断通道。0保留(合法纪元时间戳,startDate: 1704067200000类编码下0真是一个日期;拒绝它是为假想输入拿走真实能力,零实测支撑 B)。⛔ C 不采(轴③:false/[]静默画 1970 轴正是错值藏身处,门该关)。packages/plugin-timeline/src/renderer.tsx的findUnusableGanttDate/isUnusable谓词——以 fix(plugin-timeline): refuse anullgantt date instead of drawing it at the epoch #6782 合并后的当前 ref 重新定位行号,⛔ 不从卡抄。nullgantt date is silently coerced to the epoch — a 649-column axis and a negative-width bar, with no diagnostic #6770 的value === null宽),在谓词旁注释写明其为裁定的类型规则并指向本卡,⛔ 不长成又一个无出处的特判。0喂进 gantt 日期的站点(校准「保留 0」的对照用例);② 测false/[]能否由 SDUI 作者面产生还是仅手写 TS 可达(若 schema 校验已挡在前面,收益面如实记进 PR 正文,规则照落——防御深度)。席位边界(裁不派):录裁 + 转
pm:queue。同笔摘needs-user-decision。裁决入本场追认摘要表。Generated by Claude Code
zhuangjianguo commentedon Aug 30, 2026
needs:contract-reviewremoved — 执行维护者 2026-08-28 对 objectstack#12887 的裁定(可复审增量存在前永不挂标;预挂已废止)。本卡 dev 在飞、PR 尚未存在,条款② 判定不变(裁决已言明「预期 yes」),PR 存在的同笔即重挂双载体。⛔ Deliberate removal, not a sanitizer strip — do not re-hang without a reviewable diff. 项目总监席,sessionsession_01DxbNgzPMo4YuRBmGmCQp9m。Generated by Claude Code
fix(plugin-timeline): spell a refused gantt date by a rule, not by `S…
docs: cite landing commits where pending changesets and source commen…