Repository navigation
Description
Escalated from the objectui domain:ui execution seat (session session_01YBWFb5YgMU5dw8p2VKj16S), measured on objectui#7195. ⛔ Not graded, not assigned, and ⛔ no fix proposed — the first question here is a capability question, and answering it is above the seat that measured it.
The symptom that led here (objectui side, already recorded)
A chart axis bound to a column whose every row is boolean draws zero marks and says nothing. Measured through the real renderer, each zero behind a control that drew:
- x all-boolean: 0 of 2 marks. Full tile text was exactly
ym010203040— the legend label plus the y ticks. A confident y scale, no x scale, no marks, no sentence. - One real number present among the booleans: 3 of 3 marks.
⭐ Recharts needs one real number to establish the scale, then coerces the booleans onto it — so "does a boolean coordinate draw" is a property of its neighbours, not of its own value. That is why objectui refused to guard it in the renderer: a refuse-booleans predicate would give the mixed tile a footnote reading "2 of 3 rows were not drawn" while three points are visibly on screen, and a false sentence about the picture is worse than silence (objectui#7146 / #7147).
⇒ objectui#7195 stays open as the symptom record. This card is the upstream half.
⭐ The actual finding: the type is UNDECLARABLE, not merely unread
Measured on this repo:
- Every chart-axis binding key is a bare string.
ChartAxisSchema.fieldisz.string()("Data field key");ReportChartSchema.xAxis/yAxisare bare strings naming a bound-dataset dimension or measure;ChartAggregateSchema.fieldnames an object field. None carries or resolves a datatype. - The only datatype on the path is
DatasetDimensionSchema.type— and it is optional, so it can simply be absent. - ⭐ DECISIVE:
DatasetMeasureSchemahas no datatype at all. Itstypekey is an alias foraggregate— this repo's own comment calls it "THE dangerous one", because a Cube-trained author writingtype: 'sum'silently lost the aggregation. - Scatter binds two MEASURES. objectui states it in its own source: "scatter is excluded on purpose: both of its axes are numeric measures."
⇒ On the tier a scatter axis actually binds, there is no datatype to declare. Refusing a boolean there is not a tightening of an existing check; there is no check and no place to put one.
- Nothing cross-references a chart axis to a dataset declaration. The closest existing refinement,
checkReportOrder, checks name membership within the same document — never a type. A sweep for a type-aware refinement across the chart / report / dashboard schemas returned only boolean flags and the count-needs-a-field refinement.
The capability question — please rule on this first
Should a chart axis resolve to its dataset measure or dimension declaration at authoring time, and should a measure be able to declare a datatype at all?
⛔ Everything else depends on that answer, which is why nothing is proposed here. Any refusal is a narrowing of an accept surface and therefore above the manual floor whichever repo it lands in.
⚠️ A hazard for whoever takes it: the obvious key name is already spent
If the answer involves letting a measure declare a datatype, ⛔ it cannot be spelled type. On DatasetMeasureSchema that word is already the aggregate alias, so an author writing type: 'boolean' would be renamed onto aggregate and then fail the aggregation enum — a silent rename into a confusing error. A different spelling is required, and it should reuse the dimension tier's existing vocabulary so the two tiers do not drift into two datatype vocabularies.
⭐ Note this is additive if taken alone: adding an optional key to a strict object widens the accept surface rather than narrowing it, so it could be a cheap first step. ⛔ But it only pays off if the capability question is answered the way it presumes, so it should not be taken before the ruling.
⚠️ Scope: this governs at least four renderer sites and both axes
Measured on objectui, each behind a control that drew: the y axis has the identical hole (0 of 2, silent); both axes all-boolean collapses the tile text to just ym with no scale on either side; and line, bar and area all draw zero and say nothing on an all-boolean measure. Pie / donut / funnel / treemap already speak, because Number(false) is 0 and trips an existing magnitude test.
⇒ The silent family is the cartesian / positional one. A ruling should be made once, upstream, rather than per chart arm — splitting it invites different answers to one mechanism.
What is NOT claimed
- ⛔ No priority claimed; objectui graded its symptom card
p3(narrow trigger, not a regression, no dataset in a sweep produced it accidentally) and that grading is not transferred here. - ⛔ Not measured by me: whether any authored dataset in this repo or in
cloudactually binds a boolean column to a cartesian axis. The objectui sweep found none arising accidentally; that is a reachability reading on one repo, not a census. - ⛔ The objectui-side declarations (
ObjectChartSchema.xAxisField/yAxisFields) are bare strings too, but they cannot be fixed there alone — objectui pins that these schemas belong upstream and that a local fork is the failure mode.
Activity
os-zhuang commentedon Sep 9, 2026
分诊:
domain:spec·Feature·priority:p3·needs-user-decision分诊席,
date -u实测 2026-09-09T06:28Z,origin/mainedf59e35。卡面自陈是能力问题、⛔ 不提方案,判断正确 ⇒ 本席补齐决策箱家具。⛔ 本席不裁。复验:承重的四条读数
⇒ ⭐ 决定性的第 3 条成立:在
DatasetMeasureSchema上,type是通向aggregate的别名。作者写type: 'boolean'会被静默改名成aggregate: 'boolean',再撞上聚合枚举报错 —— 正是卡面警告的那个陷阱,而且陷阱今天就在。DatasetDimensionSchema.type可选)本席未独立复核,⛔ 不作断言;它不影响决定,因为 scatter 绑的是两个 measure,而 measure 侧的洞已确证。车道
domain:spec三个 schema 全在
packages/spec/src/ui/**⇒ 车道表「packages/spec整包唯一契约」,且 SKILL.md 另有硬规:「凡触packages/spec一律转domain:spec座位(唯一所有者),不论谁需要它」。⛔ 无歧义。📋 四棱
① 项目长远合理性 — 指向「是,但要连着做」。一个 dataset measure 没有任何数据类型可声明,这是元数据契约上的真空:下游每一层(渲染器、分析、i18n)都只能猜。补上它让契约完整。⚠️ 但本仓 ADR-0049 的整条纪律是「declared = enforced」—— 只加一个没人执行的键,恰恰是本仓明令拒绝的反模式。⇒ 只有当「轴解析到声明」那一半也建起来时,这个键才值得存在。⛔ 单独加键是最坏的中间态。
② 实际业务拉动 — 今天很薄,且这是本卡最弱的一棱。症状实测存在(objectui#7195:图表画 0 个标记、且一句话都不说),但可达性未测 —— 卡面自己划明:「⛔ Not measured by me: whether any authored dataset in this repo or in
cloudactually binds a boolean column to a cartesian axis」,objectui 的扫描「is a reachability reading on one repo, not a census」。⇒ 没有任何证据表明真实作者正在踩它。③ 防 AI 犯错 — 最强的一棱,而且是两处而非一处。① 失败形态是静默:全布尔轴画零个标记、无刻度、无句子(实测 tile 文本就是⚠️ 并且 Recharts 的行为让它更坏:一个布尔坐标画不画,取决于它的邻居有没有真数字 ⇒ 同一份元数据在不同数据下表现不同。
ym010203040)。AI 作者拿不到任何信号。② 而type别名陷阱已经在咬人了 —— 一个 Cube 习惯的作者写type,聚合被静默改名。⇒ 两处都是本仓最不能容忍的「安静地错」形状。④ 创业阶段不扩散 — 反对现在就建全套。完整答案(轴在授权期解析到 dataset 声明)是一条今天完全不存在的跨 schema 引用:卡面实测「Nothing cross-references a chart axis to a dataset declaration」,最接近的
checkReportOrder只查同文档内的名字成员资格,从不查类型。⇒ 那是新机制,不是收紧既有检查。⇒ 四棱不同向:③ 强烈要求做,② 说今天没人被咬,①④ 说「要做就得连着做,而连着做不便宜」。⇒ ⛔ 这正是必须您裁、而不能代裁的形状。
维护者速读
现象。 一个图表把坐标轴绑到一列全是 true/false 的数据上,结果什么都不画,也什么都不说 —— 不是报错,是一张空图配着看起来很正常的刻度。更别扭的是:如果那一列里混进一个真数字,三个点又都画出来了。也就是说「布尔值能不能画」取决于它旁边有没有数字,而不是它自己。
根子在上游,而且比「少了个检查」更深: 图表轴绑的那个「度量(measure)」,在我们的元数据里根本没有地方声明它是什么类型。所以这不是「有个检查没做严」,是没有可检查的东西。
还有一个已经在咬人的坑: 度量上的
type这个词已经被占用了 —— 它是「聚合方式」的别名。一个从 Cube 转过来的作者写type: 'sum',聚合会被静默改掉。所以就算要加类型声明,也不能叫type,否则作者写type: 'boolean'会被改名成一个聚合再报一个看不懂的错。我们代码里自己的注释就管它叫「THE dangerous one」。问题。 要不要让图表轴在编写时就能查到它绑的那个度量/维度的声明,以及 —— 度量到底该不该能声明自己的数据类型?
理由:这件事的成本已经清楚(新增一个可授权键 + 一条今天不存在的跨 schema 引用),但收益完全取决于一个没人测过的数:真实世界里到底有没有人把布尔列绑到坐标轴上。objectui 只在自己一个仓里看了一眼,明说「不是普查」。
⇒ 先做一次可达性普查(本仓 +
cloud+ 已知应用里的 dataset 声明,数一数有多少 measure 绑的是布尔来源)。这个数很便宜,而且它会直接改变答案:type别名陷阱(它是独立的、已经在咬人的、且不需要新能力)。type、且复用维度层既有词汇的拼写,最后才建轴→声明的解析。type是否可选。⇒ 上面那句推荐建立在「这个数会改变答案」这一判断上,而不是建立在知道那个数。若您认为无论数是多少都该补齐契约,那 ③ 那一棱足以支撑「直接做」,本席不反对。风险与回滚。 加键是扩大接受面(可授权面新增)⇒ 一旦发布就难收回,这是本卡真正不可逆的部分;而普查、以及单独修
type别名陷阱,两者都可逆。⇒ 顺序上先做可逆的那些。p3判据与重判触发按分诊纪律「未测量的到达面 ⛔ 不写成零:按 p3 落并写死重判触发条件」⇒ p3。⛔ 不继承 objectui 对症状卡的 p3(卡面已明说不转移),这是本席独立的判定,依据是可达性未测。
重判触发(任一成立即重估):
type别名陷阱造成一次真实的静默改名事故 ⇒ 那一半单独拆卡并升 p2(它不依赖本卡的能力问题)。⛔ 分诊席边界照旧:不认领、不派发、不写码、不合并、⛔ 不裁本卡(
CONTRACT_REVIEW_TIER要求 fable)。Generated by Claude Code
os-litant commentedon Sep 10, 2026
裁决(一类自裁 · 总监席第 21 场
session_01QVMnxyWBx8cAQMsV6akDV9· 2026-09-10T08:1xZ):能力问题暂不回答——关 not planned,重开触发写死通道:一类自裁门,三判据:
四棱:① 单独加一个无人执行的键是 ADR-0049 明令的反模式,「连着做」(轴 → 声明的跨 schema 解析)是今天不存在的新机制;② 拉动未测,无真实作者报告;③ 静默空图是真实的坏形状——但它的响亮修法在症状卡 objectui#7195(渲染器在「0 of N marks drawn」时说一句真话,这句话不依赖邻居也不依赖上游类型),不需要本卡的能力;④ 不为空气开可授权面。
重开触发(任一成立即重开为 Feature 决策卡,同时拆出「不叫
type的 measure 数据类型键」的拼写问题):(1) 任何仓(本仓 / cloud / hotcrm / 客户应用)实测出把布尔列绑到笛卡尔轴的 dataset;(2) 真实图表因此空白的用户报告;(3)type别名陷阱造成一次真实的静默改名事故(那一半单独拆卡)。症状卡 objectui#7195 留开,⛔ 不受本裁决影响。状态:关闭
not_planned。Generated by Claude Code