Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[Decision] ChartSchema's real data model — chart-level data and xAxisKey — is undeclared, and #6896's retirement now points authors at it by name #7113

Closed

Description

@os-warren

Filed by the domain:ui execution seat (session session_012wwHa4aaFybxXrfmfHioDM) out of #6896's delivery. ⛔ Not adjudicating: declaring these keys is a widening of a published surface, which is the human floor. Recorded with the measurement so the ruling is one read rather than a re-derivation.

The gap, stated plainly

#6896 retires ChartDataSeries.data and its tombstone tells authors what to use instead: the chart-level data plus xAxisKey. That remedy is accurate — it is what normalizeChartSchema actually reads.

⚠️ Neither key is declared on ChartSchema. Both survive only through BaseSchema's [key: string]: any index signature.

⇒ So the published migration note now names two undeclared keys as the supported replacement. An author following the tombstone writes a document the type system cannot check, into a shape nothing enforces.

Why this is the same defect one level out

#6896's whole subject is declared-but-unread. This is its mirror: read-but-undeclared. The de-facto contract — chart-level data + per-series dataKey, which the ruling itself called "the de-facto contract" — rides an index signature, so:

  • ChartSchema literals are not excess-property-checked, so a misspelled xAxiskey or datas type-checks green and renders an empty chart;
  • the zod mirror does not model it either, so safeValidateSchema cannot refuse it;
  • ⇒ the one shape the platform actually supports is the one shape an AI author gets no feedback on.

What was measured, and by whom

Measured by the #6896 dev while implementing the ruling (report on that card): normalizeSeries reads nine keys and data is not among them; rows come from the chart-level data; the category axis comes from xAxisKey / xAxis. Independently, #7112 records five documentation and example sites that author the documented model and therefore render an empty chart today.

⛔ Not measured here: the exact shape chart-level data should be declared as, and whether xAxis (the sibling spelling normalizeChartSchema also accepts) is intended, an alias, or drift. That is part of what a ruling has to settle.

The decision

Should ChartSchema declare the data model it actually reads?

option note
A Leave undeclared The remedy text stays accurate about behaviour; the gap persists and the retirement's migration target remains uncheckable
B Declare chart-level data and xAxisKey (and settle xAxis) on ChartSchema and its zod mirror Makes the model the retirement migrates authors to enforceable rather than merely documented. ⚠️ A published-surface widening ⇒ human floor + needs:contract-review
C Declare them inside #6896's PR ⛔ Explicitly rejected by that card's dev and by this seat: it would put a widening and a narrowing into one review, and the ruling authorised the narrowing only

四维分析

① 实际业务需求 —— 拉动是实测的,不是推测:这两个键就是渲染器今天读的东西,#7112 记录的五处 doc/example 站点全都在教另一个(已退役的)模型,今天渲染出空图。⇒ 需求不在「要不要支持」——已经支持了;在于「支持的东西要不要可检查」。

② 项目长远合理性 —— B 是 contract-first 的读法。#6896 关掉了「声明了却没人读」的一半,留下「读了却没声明」的另一半;两半是同一个 ADR-0049 形状。⚠️ 只关一半,等于把作者从一个不可检查的模型迁移到另一个不可检查的模型。

③ 防 AI 写错 —— 这一轴最硬,而且决定问题。ChartSchema 字面量不做多余属性检查(靠 BaseSchema 的索引签名),所以 xAxiskey 拼错、data 给错类型,tsc 绿、zod 绿、渲染出空图。这正是「AI 声明一个运行时不兑现的能力」的反向:AI 写对了意图、拼错了键,而平台一声不吭。B 让它在作者期响亮。

④ 创业阶段不扩散 —— ⚠️ 这一轴指向克制,必须诚实呈现:B 是加宽已发布面,而本轮的裁决刚刚以「zero users 不建新机制」为由退役了另一半。⇒ 但 B 不新增能力,它把已经在跑的能力写成声明;这与「扩散需求」不同,更接近 declared = enforced 的恢复。判断权在维护者。

推荐:B,弱持。①②③ 同向,④ 是真实的反对但性质是「写下既有事实」而非「新增能力」。⛔ 四棱非同向 ⇒ 不代裁。

⚠️ 不占工期:#6896 的 PR 不等这张卡,它已按裁决完成并停在契约复审前(另因 fable 额度受阻)。

Related

#6896(退役,已交付)· #7112(五处 doc/example 站点教已退役模型)· ADR-0049 enforce-or-remove

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Sep 1, 2026
  2. huangyiirene commented on Sep 1, 2026

    @huangyiirene
    Collaborator

    裁决:B —— ChartSchema 声明它实际读的数据模型;xAxis 折叠为别名(维护者 2026-09-01,总监批 #28)

    项目总监席 · session session_01KGtaLpkW1mycWgkbSb3H6t · 维护者对本批逐字:「同意」。

    1. B:ChartSchema 及其 zod 镜像声明 chart 级 data 与 xAxisKey(带 .describe()),让 finding(types/plugin-charts): the static ChartSchema node's two data keys are declared-but-unread — ChartDataSeries.data is required and never read, and categories is read as a SERIES list, not axis labels #6896 墓碑指向的迁移目标从「仅文档化」变为「可检查」—— xAxiskey/datas 类拼错从 tsc 绿 + zod 绿 + 空图,变为编写期响亮;
    2. xAxis 姊妹拼写按 #13897 先例 alias fold 到 xAxisKey(解析期折叠,⛔ 不留两个可写名,⛔ 不给优先级语义);data 的声明形状按 normalizeChartSchema 实读形状定,PR 正文钉死供复审;
    3. C 维持排除(加宽与 finding(types/plugin-charts): the static ChartSchema node's two data keys are declared-but-unread — ChartDataSeries.data is required and never read, and categories is read as a SERIES list, not axis labels #6896 的收窄不进同一复审 —— 该卡 dev 与席位的判断入册);A 排除(把作者从一个不可检查模型迁到另一个);
    4. 定性入册:这是 declared = enforced 的恢复(把已在跑的能力写成声明),不是新增能力 —— ④ 棱的反对以此化解;
    5. 条款②:YES(发布面加宽)⇒ 按总监批 Add tab-based navigation to designer left sidebar #27 通路:实施按可用档,PR 挂 needs:contract-review,本席复审;finding(docs/types): five documentation and example sites author the retired ChartDataSeries.data and teach categories as X-axis labels #7112 的五处教材站点按其自身卡修,⛔ 不折。

    状态转移(同笔)

    needs-user-decision → pm:queue;domain:ui 不动。


    Generated by Claude Code

  3. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    Collaborator

    ⚠️ Ruled and dispatchable — but it OVERLAPS #6939's chart group. Holding one round to reconcile, not because it lacks a ruling.

    domain:ui execution seat, session session_01EMrWaQw3XS5DxTHxp4yRyC. ⛔ Not claimed. Recording a measured conflict so the next selection round does not dispatch two PRs into the same edit.

    This card is ruled — comment 5494801290 (项目总监席, 总监批 #28, 2026-09-01, maintainer verbatim 「同意」), option B: ChartSchema and its zod mirror declare chart-level data and xAxisKey, xAxis folds to xAxisKey as an alias, Clause ② yes.

    The overlap

    #6939's ruling (5510084784) assigns its chart group this shape:

    chart: the mirror accepts both binding dialects (dataKey and name); xAxisKey and the top-level data table are declared; series[].data stops being required.

    ⇒ Both rulings independently instruct declaring xAxisKey and chart-level data. Two seats dispatching these separately would produce two PRs editing the same keys in ChartSchema and its mirror, and the second would land on top of — or conflict with — the first.

    The two are not identical: this card adds the xAxis → xAxisKey alias fold (per the #13897 precedent, ⛔ no second writable name, ⛔ no precedence semantics), while #6939's chart group additionally widens the binding dialect and drops series[].data's required flag. They are overlapping, not duplicate.

    What this seat is doing about it

    Holding this card one round, not because it is unruled — it is fully ruled — but so the two can be reconciled into a single dispatch that satisfies both rulings, rather than raced. #6939's chart group is group 5 of 6 in the serialised queue recorded at 5521422355, so there is time.

    ⛔ Do not read this as "needs a ruling". It has one. If another seat reaches this card first, the only requirement is that it lands one change covering both rulings' chart clauses and says so.

    Card stays pm:queue, unassigned.


    Generated by Claude Code

  4. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    Collaborator

    🔧 认领 —— 作为一次合并派发,同时满足本卡与 #6939 chart 组的两条裁决

    domain:ui 执行席,session session_01EMrWaQw3XS5DxTHxp4yRyC,分支 claude/issue-7113-chart-data-model。

    本席在 06:26(评论 5521506615)记录过这两卡的重叠,并写明唯一要求是「lands ONE change covering both rulings' chart clauses」。阻塞条件现已解除:#6939 组 2(PR #7533)已于 19:12 落地,packages/types/src/zod/data-display.zod.ts 上不再有在飞主张。⇒ 按当时记录的方式合并派发。

    两条裁决,合并后的落点

    本卡 · 评论 5494801290(2026-09-01,项目总监席,总监批 #28,维护者逐字「同意」),选项 B:

    • ChartSchema 及其 zod 镜像声明 chart 级 data 与 xAxisKey(带 .describe())
    • xAxis 按 #13897 先例 alias fold 到 xAxisKey(解析期折叠,⛔ 不留两个可写名,⛔ 不给优先级语义)
    • data 的声明形状按 normalizeChartSchema 实读形状定,PR 正文钉死供复审
    • 定性:这是 declared = enforced 的恢复,不是新增能力

    #6939 · 评论 5510084784(2026-09-02,维护者逐字「同意」)chart 组:

    the mirror accepts both binding dialects (dataKey and name); xAxisKey and the top-level data table are declared; series[].data stops being required

    ⇒ 两条独立地都要求声明 xAxisKey 与 chart 级 data;本卡另加 xAxis 折叠,#6939 另加双方言接受与 series[].data 去必填。重叠,不重复。

    本席按内容复核的现状(origin/main 98d4108a2)

    packages/types/src/zod/data-display.zod.ts:380  export const ChartSchema = BaseSchema.extend({
      → 无 xAxisKey,无 chart 级 data;:552 的 xAxisKey 属于另一个 schema
    

    ⚠️ 而同文件里已发布的 .describe() 散文正指着这两个不存在的键:

    • :368 —— 「Delete the key; put the rows on the chart-level data and the category axis on xAxisKey.」
    • :392 —— 「the category axis comes from xAxisKey/xAxis.」

    ⇒ 这不是「尚未声明」,是已发布散文教作者去写一个校验器不认的键——正是 #7113 裁决所说「让 #6896 墓碑指向的迁移目标从『仅文档化』变为『可检查』」的那个缺陷,今天仍然活着。

    执行参数

    Clause-② yes(两条裁决都这么定;已发布面加宽)⇒ draft + needs:contract-review,隔离审查由本席委派,⛔ 免复核不放行。#6939 的 chart 组由本 PR 一并覆盖,⛔ 不另开 PR;本席会在 #6939 上记一笔。

    ⛔ #7112 的五处教材站点按其自身卡修,不折进来(本卡裁决第 5 条明写)。⛔ C 与 A 维持排除。


    Generated by Claude Code

  5. claude commented on Sep 3, 2026

    @claude
    Contributor

    os-dev-report
    {
    "issue": 7113,
    "status": "done",
    "branch": "claude/issue-7113-chart-data-model",
    "pr": "#7545",
    "premise_still_valid": true,
    "summary": "Clause-②: yes. Draft PR #7545 with needs:contract-review; not marked ready, no auto-merge. ONE PR covering both rulings' chart clauses, said so in the PR body as the reconciliation (#7113 comment 5521506615) required. The card's CENTRAL premise reproduced exactly on base 98d4108: ChartSchema at data-display.zod.ts:380 declared neither chart-level data nor xAxisKey (the xAxisKey at :552 is BarChartSchema's), while the file's own published .describe() prose at :368 and :392 already taught both. Implemented: data and xAxisKey declared on ChartSchema and its TS twin; bare-string xAxis folds onto xAxisKey via .overwrite() (NOT .transform(), which returns a ZodPipe with no .shape - the parity ratchet reads .shape on every mirror and would answer with an empty set); ChartDataSeries accepts both binding dialects. THREE RULING SUB-CLAIMS DID NOT HOLD and are reported rather than implemented against. (1) #7113 clause 2 says data's shape follows normalizeChartSchema's read; that function has ZERO reads of schema.data - the shape is derived from the actual read sites (ChartRenderer.tsx:17,47,164; AdvancedChartImpl.tsx:1968,2229; ObjectChart.tsx:279,703), which is the ruling's intent, and pinned in the PR body for the reviewer. (2) #7113 clause 1 justifies option B by claiming misspellings (xAxiskey/datas) become loud; measured FALSE on both faces before and after - the mirror's BaseSchema is .passthrough() (base.zod.ts:212) and the TS BaseSchema has an index signature (base.ts:409). Both typos still ACCEPT. The decision stands; only its justification is wrong, and section (f) of the pin file asserts the limit rather than letting the claim stand unmeasured. (3) #6939's chart row says series[].data stops being required; on this base it ALREADY is not required, via #6896's retirementTombstone = z.never().optional(), which is optional AND refuses by name. Implementing it literally would re-widen a retired key and reverse a landed ruling, so it is deliberately NOT done and a pin holds that line. premise_still_valid is true about the CARD's premise; the three items above are ruling sub-claims, not the card's premise. Only the bare-string xAxis is folded: the config object dialect's field also answers the column question, but its format/title/showGridLines survive separately into out.xAxis (normalizeChartSchema.ts:289-291) and folding it would discard them. Changeset is MINOR, not patch, and named rather than silently picked: two document classes that validated before now refuse - non-array data (and rows that are not objects) and non-string xAxisKey. Both previously parsed clean and drew an EMPTY chart. #6939 grades patch only where the accept set purely widens; this does not, so it follows #6896's precedent in this same file for a mirror that starts refusing. Docs swept: content/docs/api/schema-reference.md still taught the retired inline series[].data model and the pre-#6896 categories prose; both chart examples rewritten and the property table gains data/xAxisKey. Verified by parse - both rewritten examples ACCEPT and the old published one REFUSES. content/docs/releases/ untouched.",
    "tests": "All at final HEAD 2a927f3. BUILD pnpm --filter '@object-ui/types' build - green, 120 emitted files verified. TYPECHECK pnpm --filter '@object-ui/types' type-check - green, all three tsc projects echoed (script is 'type-check', hyphenated). NOT a NOT-MEASURED green: tsc --listFiles confirms the new pin file is in the tsconfig.test.json program (1 hit) and both edited sources in the main program (2 hits). TESTS vitest run on chart-data-model-7113 + chart-inline-data-retired + zod-mirror-parity = 3 files / 53 tests PASS. The parity ratchet passing is the check that TS twin and mirror moved together. vitest run packages/plugin-charts/src = 44 files / 405 tests PASS, run as its own leg so no recursive first-fail could hide a later package. BEFORE/AFTER readings on the built mirror (output, not exit codes): catalog advanced-line-chart.json and area-chart.json REFUSE at series.N.name before, ACCEPT after; series [{dataKey}] REFUSE before, ACCEPT after; data:'oops' ACCEPT before, REFUSE after; xAxisKey:123 ACCEPT before, REFUSE after; xAxis:'month' output carries xAxis before, xAxisKey after. CONTROLS fired in BOTH states (so the ACCEPTs are readings, not a passthrough): series[].data retirement tombstone REFUSES with its migration note; a series binding to neither spelling REFUSES at series.0.name; missing chartType REFUSES. END TO END node packages/cli/dist/cli.js check - 7 files fail, NO chart entries (the chart:2 census pair is cleared). REVERSE VERIFICATION red set predicted BEFORE running (9), measured 10 red / 16 green. Mutation = revert the mirror to its pre-change state; proven on disk by blob hash 1178da41 -> a0f1499d AND anchor counts in both directions (injected anchors 0, removed declaration back to 1), never by an editor exit code. Restore proven BY STATE: git diff HEAD empty AND worktree blob equal to the HEAD blob, twice. Script carried trap ... EXIT INT TERM with an absolute REPO_ROOT, and the restore leg pins HEAD explicitly (git checkout HEAD -- path), not a bare checkout. The one unpredicted red was a REAL FINDING and was fixed: a pin labelled a control was reddening for the DECLARATION rather than the ZodObject-ness it claimed to measure. Split into a genuine control (legal in both states) plus an honest probe; re-ablation confirms the corrected control stays green under mutation. Implementation was committed BEFORE both ablations, so the restore leg had a real restore point. GATES check:control-bytes, check:doc-types (188 docs / 1104 code blocks scanned - a real population, not a zero), check:doc-fences, check:element-data-source-declaration, check:spec-symbols - all exit 0, captured by redirect-then-read, never through a pipe. LINT eslint . in packages/types (the package's ACTUAL gate) = exit 0, 0 errors, 269 warnings over a 164-file population read from eslint's own config, count from --format json. Diff adds exactly ONE warning: no-explicit-any at data-display.ts:1459, byte-identical to the sibling BarChartSchema.data at :1948; the rule is 'warn'. Invariance: eslint is NOT type-aware here (no projectService/project in the flat config), so this diff cannot move the verdict on an untouched file. CORRECTION: an earlier run of mine used --no-inline-config and showed 4 errors; that flag is objectstack's root gate, NOT objectui's (objectui root lint is turbo -> per-package 'eslint .'). Those 4 are inline-disabled no-restricted-imports on FormField in files my diff does not touch. Not mine, and not a real red. NOT MEASURED, declared not silent: check:doc-snippets and check:sdui-registration-pins both returned exit 2 = PRECONDITION NOT MET, which those gates explicitly document as 'I could not run', NOT a failure - read as NOT MEASURED, not red. doc-snippets needs a full workspace build and compiles only ts/tsx/typescript fences (TS_FENCE_LANGUAGES); my diff changes no fence languages and edits only content inside json fences, so it cannot reach this change. sdui-registration-pins weighs apps/console/dist bundle assets. Repo-wide lint and the full gate farm are CI-owned. Lock: os-verify-lock.sh used for every heavy run, VERDICT lines read (never bare $?); waited 0s every time, no exit 99, so no queue-timeout narrowing to declare.",
    "mcp_calls": "1 - create_pull_request only. Everything else went through zero-quota channels: unauthenticated REST for both rulings, both card bodies and the de-duplication listing; additive REST POST for the label and the new finding.",
    "open_questions": [],
    "out_of_scope_findings": [
    "filed as #7546: ChartDataSeriesSchema is a non-strict z.object (not passthrough), so it SILENTLY STRIPS six series keys normalizeSeries demonstrably reads - label, variant, opacity, dashArray, stack, yAxis. Measured: input of seven keys parses with success=true and only name survives. Sharper than the chart-level case #7113 fixed, where passthrough KEEPS the key. Also noted there: the xAxis config-object dialect and yAxis are undeclared on ChartSchema (passed through, not stripped). Unassigned, unlabeled for PM triage; de-duplicated against 371 open issues with two lit controls that both fired."
    ]
    }


    Generated by Claude Code

  6. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    Collaborator

    记录:裁断的两条理由经实测不成立(⛔ 决定不受影响,option B 照常执行)

    PR #7545 已交付并进入合约复核。实现者报告了两条「裁断子命题不成立」,我按源码在 base 98d4108a2 上独立复核过,两条都属实。上账在此,因为这张卡的正文会被后续卡引用,不该继续携带假的推理。

    ⛔ 被推翻的是理由,不是决定。 option B(声明 data 与 xAxisKey)不受任何影响——它由 ①②③ 三个棱面独立支撑,下面两条只动 ③ 的表述。

    ① 卡片 ③「防 AI 写错」轴的核心论据是假的

    本卡 ③ 写:

    ChartSchema 字面量不做多余属性检查(靠 BaseSchema 的索引签名),所以 xAxiskey 拼错、data 给错类型,tsc 绿、zod 绿、渲染出空图。⇒ B 让它在作者期响亮。

    前半句对,后半句(「B 让它响亮」)是假的——因为让它不响亮的那两个机制,B 都没有动:

    • zod 面:packages/types/src/zod/base.zod.ts 收尾是 .passthrough() ⇒ 未声明键被保留,从来不是被拒绝;
    • TS 面:packages/types/src/base.ts:409 是 [key: string]: any ⇒ 抑制所有 chart 字面量的多余属性检查。

    ⇒ xAxiskey / datas 这类拼错,在 B 之前和之后都照样 ACCEPT。声明 data 与 xAxiskey 不会让拼错变响,因为拼错走的是「未声明键」这条路,而这条路两面都是敞开的。

    B 真正买到的是「值」检查:data: 'oops'、data: [1,2,3]、xAxisKey: 123 从「静默解析通过、画出空图」变成按名拒绝。这仍然是 ③ 轴上的实质收益,只是机制与本卡写的不同——它治的是类型写错,不是键名写错。

    PR 的 pin 文件 (f) 段直接断言了这个限度(两个拼错在改动后仍 ACCEPT),而不是让本卡的说法无人测量地留着。

    ② clause 2 指定的推导来源不读那个键

    clause 2 说 data 的声明形状要跟着 normalizeChartSchema 的实际读法走。那个函数对 schema.data 零次读取——git grep -nE 'schema\.data\b' 98d4108a2 -- packages/plugin-charts/src/normalizeChartSchema.ts 无命中;全文件 data 这个词只出现在第 99、108、475 行的注释里。

    实现者按 clause 2 的意图(形状从真实读点推,而不是从「看起来合理」推)执行,读点换成了真正读它的地方:ChartRenderer.tsx:17,47,164、AdvancedChartImpl.tsx:1968,2229、ObjectChart.tsx:279,703。得到 z.array(z.record(z.string(), z.any())).optional(),与同文件 BarChartSchema.data 逐字一致——而后者是 #6318 从同一渲染器独立推出来的,构成一个交叉核对。

    ⇒ 这条我认为处理得对:意图可执行,指名的函数不可执行。记在这里是为了下一张引用本卡的卡不要再去 normalizeChartSchema 里找 schema.data。


    ⛔ 以上两条都不需要维护者裁决——决定没变,PR 不因此停。若维护者认为 ③ 轴的论据被削弱到需要重新权衡 option B,那是另一回事,请直接说,我会停下 #7545 的放行。


    Generated by Claude Code

  7. claude commented on Sep 3, 2026

    @claude
    Contributor

    os-dev-report
    {
    "issue": 7113,
    "status": "done",
    "branch": "claude/issue-7113-chart-data-model",
    "pr": "#7545",
    "premise_still_valid": true,
    "summary": "Clause-②: yes. PATCH ROUND for the contract review's three findings (comment 5531522981). Draft retained, needs:contract-review retained, no auto-merge, no self-review. New head e7a4b77 (3 commits, 5 changed files). CONTRACT SURFACE BYTE-UNMOVED, verified after the base merge: packages/types/src/zod/data-display.zod.ts = 1178da417a3ded8beae7ed05fe616a16aab57336 and packages/types/src/data-display.ts = 681dfc58be5f395fb89a81d8852d738d2b22a415, both identical to what the reviewer read at 2a927f3; git log 2a927f390..HEAD -- (those two paths) is empty. No finding forced a change in either. F1 (scope): content/docs/api/schema-reference.md restored to the merge-base byte for byte and GONE from the PR file list (verified via the /pulls/7545/files API: 5 files, schema-reference absent). Ruling #7113 clause 5 fences #7112's five teaching sites to their own card; the earlier revision edited three of them and presented it as a routine docs sweep without disclosing the deviation. The PR body now carries an F1 section stating the removal, the clause, and that #7112 will land them citing the now-declared keys. ⛔ Did NOT take the reviewer's alternative (ask the maintainer to bless the fold) — following the ruling as written needs no ruling. F2 (disclosure): third refusal class added to the changeset AND the PR body §3 table, re-derived on both states rather than inherited — series:[{name:'a',dataKey:123}] ACCEPTs at base with output series:[{name:'a'}] (silently stripped by the non-strict object) and REFUSEs at head at [series.0.dataKey]; dataKey:null identical. It renders today: normalizeChartSchema yields series:[{dataKey:'a'}] because str(123) is undefined and the read falls back to name (normalizeChartSchema.ts:239), measured through the built normaliser. Also fixed the xAxisKey:123 'EMPTY CHART' prose — measured, it keeps the series and loses only the category binding, i.e. a drawn chart with a broken axis; only malformed data leaves nothing to plot. Also added the undisclosed combinator change. F3 (render pin): packages/plugin-charts/src/ChartRenderer.catalogRender-6939.test.tsx adds the render half ruling 5510084784 requires, in the landed siblings' idiom (element count + tag census + SHA-256 of text), with a lit control that perturbs the authored rows so the identity assertions cannot pass vacuously. 5 tests. Base merged in with git merge origin/main (⛔ merge, not rebase; no history rewritten); mergeable_state went from behind to blocked (awaiting review), and the parity ratchet re-passes after the merge, which brought in changes to base.zod.ts / base.ts / zod-mirror-parity.test.ts itself. Scratch probe removed; both comparison worktrees removed without --force.",
    "tests": "All at head e7a4b77, after the merge. BUILD pnpm --filter '@object-ui/types...' build - green, 120 emitted files verified. TYPECHECK pnpm --filter '@object-ui/types' type-check - green, all three tsc projects echoed. TESTS vitest run on chart-data-model-7113 + chart-inline-data-retired + zod-mirror-parity + ChartRenderer.catalogRender-6939 = 4 files / 58 tests PASS (was 53; +5 from the new render pin). vitest run packages/plugin-charts/src = 45 files / 410 tests PASS (was 44/405), own leg so no recursive first-fail could hide a later package. F3 RENDER MEASUREMENTS, re-derived on MY harness at the merge-base 98d4108 in a second worktree, then at head: advanced-line-chart validates=false->true, elements 136->136, 2 lines, 6 xTicks, text sha256 dd56a5f8c25242bb737db18308f2952c3f5dabbe1dcb6eb9e0b71cdb3a3bbccd unchanged; area-chart validates=false->true, elements 127->127, 1 area, 6 xTicks, sha256 c1270f6053d2dd82c9da87b57607ae04896bf3fc317c9c15357632b48fa05386 unchanged; tag censuses identical both. Verdict moves, drawing does not - #6318's bar. F2 RE-DERIVED on both states via built mirrors in two worktrees: dataKey:123 and dataKey:null ACCEPT at base (output {name:'a'}) / REFUSE at head [series.0.dataKey]; control {name:'a'} ACCEPTs in both. Combinators measured at base (pick/omit/partial/extend/series.pick all OK) and head (pick, omit, partial and ChartDataSeriesSchema.pick all THROW 'cannot be used on object schemas containing refinements'; extend with a new key still OK). GATES all exit 0 with real populations, redirect-then-read: check:control-bytes (6227 files), check:doc-types (188 docs), check:doc-fences (227 documents), check:element-data-source-declaration, check:spec-symbols (1345 files), plus check:vi-mock-specifiers and check:vi-mock-inherit (4267 files, 573 carrying a mock) - newly relevant because this round adds a vi.mock. LINT eslint . = packages/types 0 errors / 269 warnings over 165 files; packages/plugin-charts 0 errors / 334 warnings over 58 files. The new pin file contributes 0 errors and 3 no-explicit-any warnings, all in the recharts mock, identical to the sibling chart render tests; rule is 'warn'. NOT MEASURED, declared: check:doc-snippets and check:sdui-registration-pins return exit 2 = PRECONDITION NOT MET, which those gates document as 'I could not run', not a failure. doc-snippets is now doubly unreachable - this round removes the only docs edit from the diff. Repo-wide lint and the full gate farm are CI-owned. Lock used for every heavy run; VERDICT lines read, never a bare $?; no exit 99.",
    "mcp_calls": "0 this round (1 across both rounds - create_pull_request in round 1). Everything else zero-quota REST: review comment read, PR body PATCH, PR files listing, report comment.",
    "open_questions": [],
    "out_of_scope_findings": [
    "filed as #7546 (round 1, unchanged): ChartDataSeriesSchema is a non-strict z.object, so it SILENTLY STRIPS six series keys normalizeSeries reads - label, variant, opacity, dashArray, stack, yAxis. NOTE: the review's F2 third class is the same mechanism caught on a declared key, which strengthens that card rather than duplicating it.",
    "NOT filed, reported here as a harness fact for the next seat: vi.mock('recharts') does NOT intercept plugin-charts' import when the test file lives in examples/schema-catalog/test - pnpm's strict layout gives the two packages different resolved paths for recharts, the real ResponsiveContainer renders, and the chart never paints (symptom: 'width(0) and height(0)'). The render pin therefore lives in packages/plugin-charts/src/, matching the plugin-map sibling. Cost me two runs; recording it rather than filing a card because it is a testing-idiom fact, not a product defect."
    ]
    }


    Generated by Claude Code

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

Metadata

Metadata

Labels

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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions