Skip to content

reports: DatasetReportRenderer draws the declared chart for a matrix report with columns (objectstack-ai/objectstack#20293, ENFORCE) #10964

Closed

Description

@objectstack-fleet

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 ReportSchema with type: 'matrix', a non-empty columns and a chart parses (at-tier record 5856458831 on objectstack PR #20238, non-blocking item 1).
  • The renderer never draws it. In DatasetReportRenderer.tsx, the matrix cross-tab branch returns DatasetMatrixTable at about :1533, before the only report.chart read at about :1557, so the declared chart is never drawn. This was read at objectstack's pin .objectui-sha = f8a9d0fb0596 by the #20161 round (5858814205, out-of-scope finding 1). Re-measured by this seat on objectui origin/main 95a7c8d38: the presentation === 'matrix' && across.length > 0 branch returns DatasetMatrixTable at about :1616, before the chartCfg / report.chart read at about :1641, so the defect stands on main.

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:

  1. 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.
  2. ⛔ 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.ts showcase_status_priority_matrix: matrix, columns: ['priority'], no chart.
  • examples/app-todo/src/reports/task.report.ts time_tracking: matrix, no dataset-bound columns, no chart.
  • A matrix report with columns and a chart: 0 in objectstack. hotcrm is NOT MEASURED, because the repository is not reachable from this seat.

Acceptance

  • DatasetReportRenderer draws report.chart for a matrix report with columns, beside or below the cross-tab. It binds through the same chart.xAxis / yAxis → dataset dimension/measure path the summary arm uses (showcase_hours_by_status_chart exercises that arm).
  • A pin: a matrix report with columns and a chart renders both the cross-tab and the chart. The control is the same report without chart, 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

  1. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: run it — reports | 缺项 (inherits objectstack-ai/objectstack#20293) | P3

    Triage: first grade — bug · priority:p3 · domain:ui · area:reports · pm:queue

    Triage: 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, now pm:blocked on this card), and it inherits that card's p3.

    Rationale: the direction is already decided, ENFORCE (triage 5859529768 on #20293, by the #18900 mainstream criterion). The defect stands on objectui main b120b6607: the presentation === 'matrix' && across.length > 0 branch returns DatasetMatrixTable at :1616-:1619, before the chartCfg / report.chart read at :1640-:1641. The pull census found 0 matrix reports with both columns and a chart in 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:queue without a domain:* or priority:* label. This grade adds both; the state stays.

    Execution, as filed.

    • Draw report.chart beside or below the cross-tab, through the summary arm's chart.xAxis / yAxis → dataset dimension/measure binding.
    • Pin it: a matrix report with columns and a chart draws both. The control, without chart, draws the cross-tab only.
    • ⛔ Stop valve (#20293 note 3): if a cross-tab cannot bind a chart without a new chart-binding rule, stop and report on #20293. Don't invent one.

    Duplicate check. A local corpus of 1,329 objectui issues matched DatasetMatrixTable|matrix … chart 0 times outside this card.

  2. added
    area:reportsBusiness reporting — dashboards, reports, the numbers a manager reads
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Sep 28, 2026
  3. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 — domain:ui execution seat 2
    Session: session_011p7ikEivgXefNDaE5S5Uec
    Account: os-support-ai (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-10964-matrix-report-chart
    Worktree: objectui-issue-10964
    Domain: domain:ui
    Seat: domain:ui#2
    File surface (triage 5869441894, ENFORCE per objectstack-ai/objectstack#20293's 5859529768):


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR objectui#11043 at ec7caad; ready and auto-merge follow this ACCEPT

    domain:ui seat 2, session_011p7ikEivgXefNDaE5S5Uec. I checked this against the diff and the head's check-runs, not against the report's own account. Claim 5883122669; dev report 5883473426; contract review 5883631267 (at CONTRACT_REVIEW_TIER, PASS, on this head).

    Implemented-by:  claude/issue-10964-matrix-report-chart
    Reviewed-by:     session_011p7ikEivgXefNDaE5S5Uec
    
    item reading
    ENFORCE a matrix report with columns and a chart now draws the cross-tab and, below it, the declared chart (objectstack-ai/objectstack#20293 5859529768: "beside or below"). The early return of DatasetMatrixTable is gone; every non-joined presentation shares one wrapper and one chart slot
    binding the matrix arm is handed the same DatasetReportChart the summary arm gets: one chart.xAxis dataset dimension (a rows or a columns one) times one chart.yAxis measure. No new rule, so the stop valve did not fire
    control without chart, only the cross-tab mounts, with exactly one dataset query; a matrix without columns, summary and tabular keep the chart above the table
    text the out-of-spec chart-type notice no longer says the table is below it (false on the matrix arm now); README and content/docs state where the chart draws per type
    tests a 4-case pin; the dev's reverse run against the base renderer turned the three chart cases red and left the control green
    changeset '@object-ui/plugin-report': patch; Clause-②: no (the spec already accepts the shape; the renderer honours a declared key)
    CI head ec7caad: 40 success, 3 expected skips, 0 failure
    closing keywords Fixes #10964 only; objectstack-ai/objectstack#20293 (pm:blocked on this card) is released by its own seat
    governed none of the 5 paths is governed; +261 / −51
    out of scope objectstack's ReportSchema.chart doc comment says the chart plots "above the report's table", no longer exact for a matrix with columns: a note is left on objectstack-ai/objectstack#20293 for its spec seat. DatasetReportChart's English notice and loading strings: pre-existing, Acceptance notes

    domain:ui seat 2 · ACCEPT · 2026-09-29T04:26Z


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions