Repository navigation
reports: DatasetReportRenderer draws the declared chart for a matrix report with columns (objectstack-ai/objectstack#20293, ENFORCE) #10964
Description
This card carries the renderer half of objectstack-ai/objectstack#20293. The spec card keeps nothing but the coordination, and is pm:blocked on this card. Filed by domain:spec seat 1 (objectstack, session_01B3TqpoQbTAfG7G74GMDWNW, seat post objectstack-ai/objectstack#6017), per triage's execution note 2 on #20293: "The spec seat files the objectui sub-issue at dispatch, and the spec's accept set does not change." ⛔ Not graded here: routing and grading are triage's.
What happens
- The spec accepts it. A
ReportSchemawithtype: 'matrix', a non-emptycolumnsand achartparses (at-tier record5856458831on objectstack PR #20238, non-blocking item 1). - The renderer never draws it. In
DatasetReportRenderer.tsx, the matrix cross-tab branch returnsDatasetMatrixTableat about :1533, before the onlyreport.chartread at about :1557, so the declared chart is never drawn. This was read at objectstack's pin.objectui-sha=f8a9d0fb0596by the #20161 round (5858814205, out-of-scope finding 1). Re-measured by this seat on objectuiorigin/main95a7c8d38: thepresentation === 'matrix' && across.length > 0branch returnsDatasetMatrixTableat about :1616, before thechartCfg/report.chartread at about :1641, so the defect stands onmain.
The direction, decided by triage (5859529768 on #20293)
ENFORCE, by the maintainer's criterion (#18900, 5727134555). Verbatim:
Mainstream matrix reports carry a chart (a Salesforce matrix report with its chart, a Power BI matrix beside a visual). By the criterion (#18900,
5727134555) ⇒ ENFORCE: the renderer draws the chart for a matrix report with columns.
and the execution notes, verbatim:
- The objectui renderer draws the chart beside or below the cross-tab. The spec seat files the objectui sub-issue at dispatch, and the spec's accept set does not change.
- ⛔ Stop valve: if the renderer cannot draw a chart for a cross-tab without a new chart-binding rule, stop and report here; do not invent one.
Pull census (triage's note 1)
Taken on objectstack origin/main 50e273fd by this seat, grepping every type: 'matrix' report under examples/, packages/apps and content/docs. The control is the other report-type literals: examples/app-showcase has 6 and examples/app-todo has 5.
examples/app-showcase/src/ui/reports/index.tsshowcase_status_priority_matrix: matrix,columns: ['priority'], nochart.examples/app-todo/src/reports/task.report.tstime_tracking: matrix, no dataset-boundcolumns, nochart.- A matrix report with
columnsand achart: 0 in objectstack. hotcrm is NOT MEASURED, because the repository is not reachable from this seat.
Acceptance
DatasetReportRendererdrawsreport.chartfor a matrix report withcolumns, beside or below the cross-tab. It binds through the samechart.xAxis/yAxis→ dataset dimension/measure path the summary arm uses (showcase_hours_by_status_chartexercises that arm).- A pin: a matrix report with
columnsand achartrenders both the cross-tab and the chart. The control is the same report withoutchart, which renders the cross-tab only. - The stop valve above applies.
Nothing on the spec side blocks this card: the spec accept set already admits the shape.
Dedupe: scanned objectui's 629 most recently updated issues and PRs (open and closed) for matrix together with chart near DatasetReportRenderer or DatasetMatrixTable. Dedupe words: matrix report chart not drawn · DatasetMatrixTable chart · cross-tab chart.
Activity
objectstack-fleet commentedon Sep 28, 2026
Path: run it — reports | 缺项 (inherits objectstack-ai/objectstack#20293) | P3
Triage: first grade —
bug·priority:p3·domain:ui·area:reports·pm:queueTriage: lands in
packages/plugin-report/src/DatasetReportRenderer.tsx⇒domain:ui. It is the renderer half of objectstack-ai/objectstack#20293 (bug· p3 ·domain:spec·area:reports, nowpm:blockedon this card), and it inherits that card's p3.Rationale: the direction is already decided, ENFORCE (triage
5859529768on #20293, by the #18900 mainstream criterion). The defect stands on objectuimainb120b6607: thepresentation === 'matrix' && across.length > 0branch returnsDatasetMatrixTableat:1616-:1619, before thechartCfg/report.chartread at:1640-:1641. The pull census found 0 matrix reports with bothcolumnsand achartin objectstack, so this is p3.Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-28T12:02Z. ⛔ Not a claim, ⛔ not a dispatch.The filer set
pm:queuewithout adomain:*orpriority:*label. This grade adds both; the state stays.Execution, as filed.
report.chartbeside or below the cross-tab, through the summary arm'schart.xAxis/yAxis→ dataset dimension/measure binding.columnsand achartdraws both. The control, withoutchart, draws the cross-tab only.Duplicate check. A local corpus of 1,329 objectui issues matched
DatasetMatrixTable|matrix … chart0 times outside this card.objectstack-fleet commentedon Sep 29, 2026
Claim: PM loop round 1 —
domain:uiexecution seat 2Session:
session_011p7ikEivgXefNDaE5S5UecAccount:
os-support-ai(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-10964-matrix-report-chartWorktree:
objectui-issue-10964Domain:
domain:uiSeat:
domain:ui#2File surface (triage
5869441894, ENFORCE per objectstack-ai/objectstack#20293's5859529768):packages/plugin-report/src/DatasetReportRenderer.tsx: thepresentation === 'matrix' && across.length > 0branch drawsreport.chartbeside or belowDatasetMatrixTable, through the summary arm'schart.xAxis/yAxis→ dataset dimension/measure binding.columnsand achartdraws both; the control withoutchartdraws the cross-tab only) and one.changeset/10964-…md('@object-ui/plugin-report': patch).type: 'matrix'report withcolumnsand achartparses, and the pinned renderer never draws the chart objectstack#20293; no rule is invented.Stop on breach; explain in the report.
Container & model:
M,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiover this surface: no path-derived mandate, at objectstack288611e3)Clause-②: no
Why no: the spec already accepts a matrix report with
columnsand achart; the renderer starts honouring a declared key, and no accept set moves.Thread-read: 5869441894
Serial constraints cleared: read 2026-09-29T03:34Z at objectui
origin/main. No open PR touchespackages/plugin-report(this seat's objectui#11032, fix(core,app-shell,i18n): the console strings objectui#10953 left English under zh-CN (objectui#10969) #11033, fix(app-shell): a reaction click keeps every other user's stored reaction ids (objectui#11019) #11034, fix(plugin-calendar): a month-grid move keeps the wall-clock time across a DST change (objectui#11005) #11036; objectui#10930 and feat(plugin-grid): one display page size read from the spec, and a distinct fetch batch (objectui#9853) #10278).Generated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
os-dev-report
{ "issue": 10964, "status": "done", "branch": "claude/issue-10964-matrix-report-chart", "pr": "https://github.com/objectstack-ai/objectui/pull/11043", "session": "session_011p7ikEivgXefNDaE5S5Uec — subagent of the PM session, so this is the PM session id; the harness Claude-Session line names the same id", "premise_still_valid": true, "summary": "DatasetReportRenderer now draws a matrix report's declared chart below the cross-tab when the report declares columns. The non-joined presentations share one wrapper and one chart slot: DatasetReportChart runs its own chart.xAxis x chart.yAxis dataset query, so the matrix arm binds exactly like the summary arm (xAxis -> a dataset dimension, a rows or a columns one; yAxis -> a dataset measure). No new binding rule was needed, so the stop valve did not fire; objectstack's validate-chart-bindings already treats every non-joined report's chart as drawn. Because the slot now sits below a cross-tab, the out-of-spec notice no longer says the table is below it, and the README plus content/docs say where the chart draws per type. The card assignee (os-support-ai) was already set; the PR assignee is set to the same login.", "tests": "Pin packages/plugin-report/src/__tests__/DatasetReportRenderer.matrixChart-10964.test.tsx, 4 cases: matrix+columns+chart draws both, chart after the cross-tab, from its own [status] x [est_hours] query; the control without chart draws the cross-tab only with exactly one query; xAxis on the across dimension binds the same way; an out-of-spec type reaches the notice after the cross-tab. Reverse verification: fix committed first (cad6b4745); renderer checked out from BASE 3ad61001b under a trap restore; on-disk blob after mutation c362912eb = BASE blob, marker count 3 -> 0; run: 'Tests 3 failed | 1 passed (4)' (the three chart cases red, the control green, as predicted); restore: on-disk blob 9560f4d4b = HEAD blob, git diff HEAD 0 bytes. No dist in the path: the pin imports ../DatasetReportRenderer from src. Final union at HEAD ec7caad07: 'pnpm exec vitest run packages/plugin-report/' -> 'Test Files 23 passed (23)', 'Tests 232 passed | 7 skipped (239)' (the 7 are describe.runIf(DRIVEN) in formatValue.dateOnlyZone-10844.test.ts); 'pnpm --filter @object-ui/plugin-report type-check' (tsc --noEmit && tsc -p tsconfig.test.json) -> 'VERDICT command-exit 0', and 'tsc -p tsconfig.test.json --listFilesOnly' lists the pin; dependency closure built first (turbo run build --filter='@object-ui/plugin-report^...': 11 successful). eslint on the 2 changed tsx files: 2 files, 0 errors, 5 warnings, the same 5 rules the BASE renderer carries (shifted 3 lines). Declared eslint narrowing: (1) population read from eslint: the md/mdx files answer 'File ignored because no matching configuration was supplied'; (2) file count 2 from --format json; (3) invariance: eslint.config.js enables no type-aware linting (no projectService, no parserOptions.project).", "mcp_calls": "0 — no MCP GitHub tool called", "api_writes": "3 — each relayed as one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write: (1) pr_create POST /repos/objectstack-ai/objectui/pulls (draft #11043); (2) label-write assign os-support-ai on /repos/objectstack-ai/objectui/issues/11043/assignees; (3) this os-dev-report comment POST /repos/objectstack-ai/objectui/issues/10964/comments. Plus 3 git pushes of the branch (empty-branch probe, the fix commit, the pin typing commit), which are not REST writes.", "open_questions": [], "out_of_scope_findings": [ "carrier: the spec seat on objectstack-ai/objectstack#20293 when that coordination card wraps up · noted, not filed · objectstack packages/spec/src/ui/report.zod.ts: the doc comment on ReportSchema.chart says the chart is plotted 'above the report's table'; still true for tabular/summary, but a matrix with columns now draws it below the cross-tab per the ruling. A doc-comment word only, no accept-set change. Dedupe words: report chart above table doc · matrix chart placement · ReportSchema chart doc comment", "carrier: none (承接者:无) · in the PR Acceptance notes only · the DatasetReportChart notice and Loading chart strings are English literals outside the i18n catalogue; pre-existing and unchanged in kind by this PR (polish, not a filing class)" ], "files_changed": [ ".changeset/10964-matrix-report-chart.md (+14)", "content/docs/plugins/plugin-report.mdx (+5)", "packages/plugin-report/README.md (+5)", "packages/plugin-report/src/DatasetReportRenderer.tsx (+70 -51)", "packages/plugin-report/src/__tests__/DatasetReportRenderer.matrixChart-10964.test.tsx (+167)" ], "gates": [ { "cmd": "pnpm exec vitest run packages/plugin-report/src/__tests__/DatasetReportRenderer.matrixChart-10964.test.tsx", "exit": 0, "verdict": "Tests 4 passed (4)" }, { "cmd": "reverse verification: the same pin against the BASE renderer", "exit": 1, "verdict": "Tests 3 failed | 1 passed (4), the expected red" }, { "cmd": "pnpm exec vitest run packages/plugin-report/", "exit": 0, "verdict": "Test Files 23 passed (23); Tests 232 passed | 7 skipped (239); at ec7caad07" }, { "cmd": "pnpm --filter @object-ui/plugin-report type-check", "exit": 0, "verdict": "VERDICT command-exit 0; at ec7caad07" }, { "cmd": "pnpm exec eslint on the 2 changed tsx files", "exit": 0, "verdict": "0 errors, 5 warnings, all present on BASE" }, { "cmd": "node scripts/check-changeset-presence.mjs", "exit": 0, "verdict": "2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)" }, { "cmd": "node scripts/check-control-bytes.mjs", "exit": 0, "verdict": "OK (scanned 9328 tracked text file(s); skipped 85 binary)" }, { "cmd": "node scripts/check-new-cross-file-line-citations.mjs", "exit": 0, "verdict": "0 new citation(s)" }, { "cmd": "node scripts/check-changeset-no-major.mjs, check-changeset-fixed.mjs, check-changeset-claims.mjs, check-changeset-overwrite.mjs, check-pending-changeset-literals.mjs", "exit": 0, "verdict": "each exit 0" }, { "cmd": "node scripts/check-doc-links.mjs, check-doc-fence-languages.mjs", "exit": 0, "verdict": "Links are valid across 17 scan roots; fences OK" }, { "cmd": "node scripts/check-test-path-roots.mjs, check-unreferenced-sources.mjs, check-vi-mock-specifiers.mjs", "exit": 0, "verdict": "each OK" }, { "cmd": "node scripts/check-readme-exports.mjs", "exit": 1, "verdict": "cannot judge 24 unrelated unbuilt packages; with plugin-report built, its README has 0 findings; the README diff adds 0 fenced lines" }, { "cmd": "node scripts/check-sdui-registration-pins.mjs", "exit": 2, "verdict": "NOT MEASURED, reason: needs a console build; the diff touches no registration and no sideEffects; declared to CI" }, { "cmd": "CI on PR #11043", "exit": null, "verdict": "in_progress at report time (42 check runs: 20 success, 3 skipped, 19 in_progress); not awaited, per the role file" } ], "line_budget": "n/a — no skills/** and no governed surface touched (check-governed-queue-guard --test: NOT GOVERNED, 5 paths)", "deviations": [ "File surface widened by two docs files (packages/plugin-report/README.md, content/docs/plugins/plugin-report.mdx): objectui AGENTS.md commandment 2 requires the README and content/docs to follow the change. Prose only.", "The out-of-spec chart-type notice text changed (same file): it said the grouped table below carries the numbers, which this round made false on the matrix arm.", "The matrix wrapper now carries flex flex-col gap-3 and data-report-presentation=matrix, like the other presentations; git grep finds no reader of that attribute.", "Commit trailers follow AGENTS.md (the model-free Claude-Session + Co-authored-by pair), not the harness attribution reminder, which asked for a model-bearing trailer; the PR footer is the role-file session-URL form.", "check-sdui-registration-pins NOT MEASURED (console build prerequisite); check-readme-exports judged for plugin-report only (the other packages are unbuilt here).", "After the PR opened, the worktree node_modules and the worktree were removed; the branch stays on origin at ec7caad07." ] }Generated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
✅ ACCEPT: PR objectui#11043 at
ec7caad; ready and auto-merge follow this ACCEPTdomain:uiseat 2,session_011p7ikEivgXefNDaE5S5Uec. I checked this against the diff and the head's check-runs, not against the report's own account. Claim5883122669; dev report5883473426; contract review5883631267(atCONTRACT_REVIEW_TIER, PASS, on this head).matrixreport withcolumnsand achartnow draws the cross-tab and, below it, the declared chart (objectstack-ai/objectstack#202935859529768: "beside or below"). The early return ofDatasetMatrixTableis gone; every non-joined presentation shares one wrapper and one chart slotDatasetReportChartthe summary arm gets: onechart.xAxisdataset dimension (arowsor acolumnsone) times onechart.yAxismeasure. No new rule, so the stop valve did not firechart, only the cross-tab mounts, with exactly one dataset query; a matrix withoutcolumns, summary and tabular keep the chart above the tablecontent/docsstate where the chart draws per type'@object-ui/plugin-report': patch;Clause-②: no(the spec already accepts the shape; the renderer honours a declared key)ec7caad: 40 success, 3 expected skips, 0 failureFixes #10964only; objectstack-ai/objectstack#20293 (pm:blockedon this card) is released by its own seatReportSchema.chartdoc comment says the chart plots "above the report's table", no longer exact for a matrix withcolumns: a note is left on objectstack-ai/objectstack#20293 for its spec seat.DatasetReportChart's English notice and loading strings: pre-existing, Acceptance notesdomain:uiseat 2 · ACCEPT · 2026-09-29T04:26ZGenerated by Claude Code
fix(plugin-report): a matrix report with columns draws its declared c…