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 }}
Repository navigation
Report chart draws the seriesBy split: query the second dimension and pivot it into grouped series #28206
Filing gate: ③ the renderer half of #27974, whose contract half lands in PR #28191 (claim 6526104358 names this follow-up; contract review 6528174510 PASS). ⛔ Not a claim. Triage sets the lane and grade.
Reach: any report that wants a bar per X split by Y. HotCRM opportunity_funnel_owner_stage (a bar per owner, split by stage) still falls back to an owner × stage matrix (hotcrm#2379) until the renderer reads the key.
ReportChartSchema.seriesBy is declared and checked at publish (validateChartBindings, chart-dimension-unknown), and its liveness row (packages/spec/liveness/report.json, chart.children.seriesBy) is planned with an author warning: declared, not yet drawn.
ui/packages/plugin-report/src/DatasetReportRenderer.tsxDatasetReportChart queries exactly [xAxis] × [yAxis] (≈L1210–1230, L1421), so the split is never drawn.
Wanted
The renderer widens the report chart query to [xAxis, seriesBy] × [yAxis] when seriesBy is set and passes the rows through buildChartSeries (ui/packages/core/src/utils/chart-series.ts, the existing two-dimension / one-measure pivot, ≈L592), with a test and an ablation.
The liveness row chart.children.seriesBy moves from planned to live in the same PR, with the reader as evidence.
Riders named by the contract review 6528174510 (should-fix, non-blocking): S1 a warning in validateChartBindings when seriesBy === xAxis (the pivot would make every x bucket its own series); S2 the chart row's stale groupBy sentence in the liveness note.
Blocked-by: #28191 is added to the body. pm:blocked.
One-PR cross-domain exception: only packages/spec/liveness/report.json, for the seriesBy row and the stale groupBy note (S2). Rider S1, the seriesBy === xAxis warning in validateChartBindings, is spec code. It stays with the spec lane and does not ride this PR.
Claim: PM loop round 1 · 2026-10-31T03:24Z
Session: session_01L9qibxgfM8p8t3fo6y9eFK (seat; card thread session_01L9qibvUw5sBjvzer4Z7WHt)
Account: os-tesla
Branch: claude/project-thread-suz06i (card thread; the platform assigns the thread's branch)
Worktree: objectstack-28206
Domain: domain:ui
Seat: domain:ui#2
File surface: ui/packages/plugin-report/**, ui/packages/core/src/utils/chart-series.ts only if the pivot needs a change, packages/spec/liveness/report.json (one row + note), the validateChartBindings file for rider S1, tests, root changesets (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT (default judgment tier), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6530264156
Premise: holds
Serial constraints cleared: no live claim names plugin-report; the S1 warning rider may touch packages/spec — the dev measures and reports so the seat routes its contract review
{
"issue": 28206,
"status": "done",
"branch": "claude/project-thread-suz06i",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28305",
"session": "session_01L9qibvUw5sBjvzer4Z7WHt",
"premise_still_valid": true,
"summary": "DatasetReportChart reads chart.seriesBy: on a series chart its own query becomes [xAxis, seriesBy] x [yAxis] and buildChartSeries takes its existing pivot branch (one row per x bucket, one series per split value); series follow the split dimension's declared option order with the empty group last, and an authored series[] entry naming a split value lands its presentation with a pickLocalized label. Liveness chart.children.seriesBy planned -> live (authorWarn dropped), S2 stale groupBy sentence replaced, state-counts regenerated. S1 dropped per the seat (spec lane); the lint header and the chart-axis-not-selected explanation sentences this change made false were corrected, prose only. chart-series.ts unchanged.",
"tests": "head 39eb423b. pnpm --dir ui exec vitest run packages/plugin-report/: Test Files 31 passed (31), Tests 282 passed | 7 skipped, VERDICT command-exit 0. New DatasetReportRenderer.chartSeriesBy-28206.test.tsx: 4 passed. Ablation via scripts/ablation-replace.mjs (split arm of queryDimensions -> [xAxis]; anchor 1->0, blob 280c006b->983b4e78): predicted 3 red / control green, measured 3 failed | 1 passed; restored blob == HEAD 280c006b, git diff HEAD empty (source-imported test, no dist leg). pnpm --filter @objectstack/lint test: 181 files, 7679 passed. Type-checks: @objectstack/lint typecheck exit 0, @object-ui/plugin-report type-check exit 0.",
"gates": "dispatch-gates --ran on head 39eb423b: 71 derived, 70 run all exit 0, 1 NOT MEASURED (pnpm check:dual-build-cjs-loads exit 3, PREREQUISITE NOT MET, needs every package dist; declared to CI). check:liveness red then green after gen:liveness-counts; check-plugin-teardown-shape --self-test exit 3 on shallow clone then 0 after fetching its pinned fixture commit. check-sdui-manifest + --self-test exit 0. Record: /mnt/project-files/ui-seat-2/r2026-10-31/out/28206-gates-ran-39eb423b.list. CI check-runs: in_progress at report time.",
"line_budget": "PR #28305: +360 / -52, 7 files (under the 3000 human-merge threshold)",
"files_changed": [
".changeset/28206-report-chart-series-by-renderer.md",
"packages/lint/src/rule-explanations.ts",
"packages/lint/src/validate-chart-bindings.ts",
"packages/spec/liveness/report.json",
"packages/spec/liveness/state-counts/report.md",
"ui/packages/plugin-report/src/DatasetReportRenderer.tsx",
"ui/packages/plugin-report/src/__tests__/DatasetReportRenderer.chartSeriesBy-28206.test.tsx"
],
"deviations": [
"S1 not implemented: seat ruling (spec lane per triage 6528521739); measured location packages/lint/src/validate-chart-bindings.ts is in PR Acceptance notes",
"packages/lint prose edits (validate-chart-bindings.ts header + ownSelection doc, rule-explanations.ts chart-axis-not-selected paragraph) ride as made-false-by-this-change corrections, ordered by the seat; no rule, severity or finding change",
"test:repo (vitest repo project) not run locally; CI's"
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "6 — reads only: issue_read x3 (get, get_comments x2), pull_request_read x1 (get); 0 writes",
"api_writes": "2 — relay pr_create (fleet-write run 41167081801, PR #28305); this os-dev-report comment via post-stamped.mjs",
"open_questions": [],
"out_of_scope_findings": [
"class: c · reach: named producer (a report chart of type pie/donut/funnel with seriesBy parses, then draws the single-series refusal notice) · evidence: AdvancedChartImpl OneSeriesFamilyRefusal for pie/donut/funnel with 2+ groups; ReportChartSchema does not refuse seriesBy on single-series types · dedupe words: report chart seriesBy pie funnel single-series · carrier: spec lane with S1, noted not filed"
]
}
Delivered: a report chart with seriesBy draws one bar series per second-dimension value (liveness row live). Card closed by Fixes; pm:dispatched removed. Owed to the spec lane (hand-off on the spec seat mailbox): rider S1 (seriesBy === xAxis warning in packages/lint/src/validate-chart-bindings.ts) and the finding that a pie/donut/funnel report with seriesBy parses, then draws the one-series refusal.
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 经营报表 | none | P②
Triage: p3 ·
domain:ui·area:reports·pm:blockedon #28191 · 2026-10-30T17:00Z⛔ Not a claim.
ReportChartSchema.seriesBy. The parent Report chart: split a series by a second dataset dimension #27974 is p3, so this card is p3 too.Blocked-by: #28191is added to the body.pm:blocked.packages/spec/liveness/report.json, for theseriesByrow and the stalegroupBynote (S2). Rider S1, theseriesBy === xAxiswarning invalidateChartBindings, is spec code. It stays with the spec lane and does not ride this PR.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: unblocked · p3 · 2026-10-30T18:18Z
⛔ Not a claim.
Blocked-by: #28191, and PR feat(spec): a report chart can split its bars by a second dataset dimension (chart.seriesBy) #28191 merged at 2026-10-30T17:15Z.pm:blockedis removed. It stays at p3 withoutpm:queue(「低优先级的先不考虑」).Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#2 · os-tesla · session_01L9qibxgfM8p8t3fo6y9eFK
Claim: PM loop round 1 · 2026-10-31T03:24Z
Session:
session_01L9qibxgfM8p8t3fo6y9eFK(seat; card threadsession_01L9qibvUw5sBjvzer4Z7WHt)Account:
os-teslaBranch:
claude/project-thread-suz06i(card thread; the platform assigns the thread's branch)Worktree:
objectstack-28206Domain:
domain:uiSeat:
domain:ui#2File surface:
ui/packages/plugin-report/**,ui/packages/core/src/utils/chart-series.tsonly if the pivot needs a change,packages/spec/liveness/report.json(one row + note), thevalidateChartBindingsfile for rider S1, tests, root changesets (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT (default judgment tier),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6530264156
Premise: holds
Serial constraints cleared: no live claim names
plugin-report; the S1 warning rider may touchpackages/spec— the dev measures and reports so the seat routes its contract reviewobjectstack-fleet commentedon Oct 31, 2026
domain:ui#2 · os-tesla · session_01L9qibvUw5sBjvzer4Z7WHt
os-dev-report
{ "issue": 28206, "status": "done", "branch": "claude/project-thread-suz06i", "pr": "https://github.com/objectstack-ai/objectstack/pull/28305", "session": "session_01L9qibvUw5sBjvzer4Z7WHt", "premise_still_valid": true, "summary": "DatasetReportChart reads chart.seriesBy: on a series chart its own query becomes [xAxis, seriesBy] x [yAxis] and buildChartSeries takes its existing pivot branch (one row per x bucket, one series per split value); series follow the split dimension's declared option order with the empty group last, and an authored series[] entry naming a split value lands its presentation with a pickLocalized label. Liveness chart.children.seriesBy planned -> live (authorWarn dropped), S2 stale groupBy sentence replaced, state-counts regenerated. S1 dropped per the seat (spec lane); the lint header and the chart-axis-not-selected explanation sentences this change made false were corrected, prose only. chart-series.ts unchanged.", "tests": "head 39eb423b. pnpm --dir ui exec vitest run packages/plugin-report/: Test Files 31 passed (31), Tests 282 passed | 7 skipped, VERDICT command-exit 0. New DatasetReportRenderer.chartSeriesBy-28206.test.tsx: 4 passed. Ablation via scripts/ablation-replace.mjs (split arm of queryDimensions -> [xAxis]; anchor 1->0, blob 280c006b->983b4e78): predicted 3 red / control green, measured 3 failed | 1 passed; restored blob == HEAD 280c006b, git diff HEAD empty (source-imported test, no dist leg). pnpm --filter @objectstack/lint test: 181 files, 7679 passed. Type-checks: @objectstack/lint typecheck exit 0, @object-ui/plugin-report type-check exit 0.", "gates": "dispatch-gates --ran on head 39eb423b: 71 derived, 70 run all exit 0, 1 NOT MEASURED (pnpm check:dual-build-cjs-loads exit 3, PREREQUISITE NOT MET, needs every package dist; declared to CI). check:liveness red then green after gen:liveness-counts; check-plugin-teardown-shape --self-test exit 3 on shallow clone then 0 after fetching its pinned fixture commit. check-sdui-manifest + --self-test exit 0. Record: /mnt/project-files/ui-seat-2/r2026-10-31/out/28206-gates-ran-39eb423b.list. CI check-runs: in_progress at report time.", "line_budget": "PR #28305: +360 / -52, 7 files (under the 3000 human-merge threshold)", "files_changed": [ ".changeset/28206-report-chart-series-by-renderer.md", "packages/lint/src/rule-explanations.ts", "packages/lint/src/validate-chart-bindings.ts", "packages/spec/liveness/report.json", "packages/spec/liveness/state-counts/report.md", "ui/packages/plugin-report/src/DatasetReportRenderer.tsx", "ui/packages/plugin-report/src/__tests__/DatasetReportRenderer.chartSeriesBy-28206.test.tsx" ], "deviations": [ "S1 not implemented: seat ruling (spec lane per triage 6528521739); measured location packages/lint/src/validate-chart-bindings.ts is in PR Acceptance notes", "packages/lint prose edits (validate-chart-bindings.ts header + ownSelection doc, rule-explanations.ts chart-axis-not-selected paragraph) ride as made-false-by-this-change corrections, ordered by the seat; no rule, severity or finding change", "test:repo (vitest repo project) not run locally; CI's" ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "6 — reads only: issue_read x3 (get, get_comments x2), pull_request_read x1 (get); 0 writes", "api_writes": "2 — relay pr_create (fleet-write run 41167081801, PR #28305); this os-dev-report comment via post-stamped.mjs", "open_questions": [], "out_of_scope_findings": [ "class: c · reach: named producer (a report chart of type pie/donut/funnel with seriesBy parses, then draws the single-series refusal notice) · evidence: AdvancedChartImpl OneSeriesFamilyRefusal for pie/donut/funnel with 2+ groups; ReportChartSchema does not refuse seriesBy on single-series types · dedupe words: report chart seriesBy pie funnel single-series · carrier: spec lane with S1, noted not filed" ] }objectstack-fleet commentedon Oct 31, 2026
domain:ui#2 · os-tesla · session_01L9qibxgfM8p8t3fo6y9eFK
Landed · 2026-10-31T14:45Z
39eb423b(PASS 6539092307, ACCEPT 6540300747), merge commit2d3aa8cad0origin/main2d3aa8cad0(git merge-base --is-ancestor)Delivered: a report chart with
seriesBydraws one bar series per second-dimension value (liveness row live). Card closed byFixes;pm:dispatchedremoved. Owed to the spec lane (hand-off on the spec seat mailbox): rider S1 (seriesBy === xAxiswarning inpackages/lint/src/validate-chart-bindings.ts) and the finding that a pie/donut/funnel report withseriesByparses, then draws the one-series refusal.