@@ -14704,6 +14704,68 @@ const step18: MigrationStep = {
1470414704 + 'reports no `component-props-unknown-key` / `component-props-invalid` finding for the '
1470514705 + 'rail.',
1470614706 },
14707+ // #20161 — the judgement half of `report-joined-chart-removed`, owed under
14708+ // #17152 ruling B (one D3 entry per retirement family, even when a lossless D2
14709+ // exists). The D2 conversion strips a joined report's `chart` mechanically, at
14710+ // both coordinates, and that strip changes nothing that renders. What it cannot
14711+ // do is decide whether the author MEANT a chart: that intent has no place to go
14712+ // on a joined report, so moving it to a report that draws one is the author's
14713+ // call. Its own family, not an extension of
14714+ // `ui-report-joined-container-selection-refused`: that entry is the enforce arm
14715+ // for four selection keys that stay declared and has no D2 at all, while this one
14716+ // retires a declared block key, refuses a container key, and pairs with a D2.
14717+ {
14718+ id: 'ui-report-joined-chart-retired',
14719+ surface:
14720+ '`report.blocks[].chart` (REMOVED from the joined report block shape) and `report.chart` on '
14721+ + 'a report whose `type` is `joined` (REFUSED by `ReportSchema`\'s refinement) — a chart '
14722+ + 'anywhere on a joined report',
14723+ replacement:
14724+ 'nothing on the joined report: a joined report draws each block as a table and has no chart '
14725+ + 'channel at either level. Delete the `chart`. If the chart was wanted, give the slice it '
14726+ + 'was meant to plot a report of its own — `type` `tabular`, `summary` or `matrix`, binding '
14727+ + 'the same `dataset` the block bound, selecting the dimension and measure the chart names '
14728+ + 'in its `rows` and `values` — carry the `chart` over to that report\'s top level, where '
14729+ + '`xAxis` names a dataset dimension and `yAxis` a measure exactly as before, and reach it '
14730+ + 'from the app navigation beside the joined report.',
14731+ reason:
14732+ 'ADR-0049 enforce-or-remove. Nothing ever drew a chart on a joined report: the renderer\'s '
14733+ + 'joined branch draws each block as a table and returns before its one read of the '
14734+ + 'report\'s `chart`, and no renderer reads a block\'s `chart` at all — measured at this '
14735+ + 'repo\'s `.objectui-sha` pin `f8a9d0fb0596f4521076628e2bbfe27e6ce67d52` '
14736+ + '(`DatasetReportRenderer.tsx`, joined branch at lines 1462-1524, the only chart read at '
14737+ + '1557). So both coordinates parsed, passed the `validate-chart-bindings` lint (which '
14738+ + 'resolved their axes as if they would plot), and showed tables only. The D2 conversion '
14739+ + '`report-joined-chart-removed` already REPAIRS THE DATA: it strips both from authored '
14740+ + 'sources on a chain replay and from stored `sys_metadata` rows at rehydration, a lossless '
14741+ + 'delete because neither value ever rendered. What it cannot repair is intent. Deleting '
14742+ + 'the key leaves the report looking exactly as it always did — which is the problem when '
14743+ + 'the author believed a chart was there: they were reading a chart that never existed, '
14744+ + 'and only they know whether they wanted one. A walker cannot move it anywhere either: a '
14745+ + 'joined report has no chart channel, and creating a new report, choosing its type and '
14746+ + 'placing it in navigation are authoring decisions, not rewrites. The Studio report form '
14747+ + 'offered a block chart input until this change, so a stored row carrying one is a real '
14748+ + 'shape, not a hypothetical. Ships at once, no deprecation window: there is no window in '
14749+ + 'which a key the renderer never reads does anything. `chart` on every non-joined report '
14750+ + 'is unchanged — it is that report\'s live embedded chart.',
14751+ acceptanceCriteria:
14752+ 'WHICH DOOR: the refusal is the spec schema\'s, so it lands wherever a report is parsed '
14753+ + 'through `@objectstack/spec` — `defineReport`, `os validate` / `os build`, and the metadata '
14754+ + 'save door (the `report` entry of the metadata type registry, answered as '
14755+ + '`INVALID_METADATA` with status 422). A block `chart` is refused as an unrecognized key '
14756+ + 'on that block with the upgrade prescription; a container `chart` on a joined report is '
14757+ + 'one `custom` issue at `chart`. (1) No joined report carries a `chart` at either level: '
14758+ + 'run `os migrate meta --from 17` to list the mechanical strips for existing sources, and '
14759+ + 'the stored-row seams replay the same strip for rows at rest. (2) For every joined report '
14760+ + 'that carried one, decide whether the chart was wanted; if it was, a non-joined report '
14761+ + 'now binds that slice\'s dataset and carries the chart, and its `xAxis` / `yAxis` resolve '
14762+ + '(`validate-chart-bindings` checks them there). (3) Check the rendered joined report: it '
14763+ + 'renders exactly as before, because the chart was never drawn. A joined report with no '
14764+ + '`chart` parses byte-identically to before, and every non-joined report is untouched. '
14765+ + 'Census at the time of the change: zero joined reports with a chart in this repo\'s '
14766+ + 'example apps and in the hotcrm reference app, against a lit control (non-joined reports '
14767+ + 'carrying a chart: one and five).',
14768+ },
1470714769 {
1470814770 id: 'ui-report-joined-container-selection-refused',
1470914771 surface: 'report selection keys on a `joined` container — a top-level `dataset`, or a '
0 commit comments