Found while surveying which platform rules actually fire on objectstack-ai/hotcrm (its #1621, step 3 of epic #1579). Read-only survey, report-first, unassigned.
Measured against the pinned @objectstack/lint@17.3.0 in that app's node_modules (never the platform source tree), hotcrm at 1670557. Every injection was proven to reach disk by blob hash before any conclusion was drawn, and restored by blob hash verified by observation.
Fact 1 — a report with no chart key is never validated at all
validate-chart-bindings.ts reaches a report only through checkReportChart, which opens:
const checkReportChart = (chart, dataset, values, where, path) => {
if (!isRec(chart)) return;
That closure is the only entrance that receives report.dataset. A report authored without a chart therefore never has its dataset resolved.
- Injection: on
pipeline_coverage_by_quarter (a type: 'matrix' report that declares no chart), dataset: 'opportunity_metrics' to dataset: 'opportunity_metrics_nope'.
objectstack lint --json gives passed: true, errors: 0, exit 0, no new finding.
- Working control, same file, same harness, same run design: the identical edit on
opportunities_by_stage, which does declare a chart, produces chart-dataset-unknown at error, exit 1.
Fact 2 — rows / columns are never checked on any report, charted or not
checkReportChart forwards values as the measure selection and the two chart axes. The report's dimension selection (rows, columns) is never passed to check().
- Injection: on the charted
opportunities_by_stage, rows: ['stage'] to rows: ['stage_nope'] gives exit 0, no finding.
- Working control, same report, same run:
values: ['total_amount', 'avg_probability'] to values: ['total_amount_nope', 'avg_probability'] produces chart-measure-unknown at error plus chart-axis-not-selected at warning, exit 1.
So on one and the same report object, the measure selection is validated and the dimension selection is not.
Consequence
A report bound to a dataset that does not exist, or grouping on a dimension its dataset does not declare, publishes clean — os lint exits 0 and names nothing. On hotcrm the local test test/analytics-integrity.test.ts catches both cases, which is how the asymmetry was found; that assertion consequently cannot be retired against these rule ids.
Dedupe
Nearest existing cards, both read in full, neither duplicating this:
Neither addresses the chartless-report entrance or the rows/columns omission.
Found while surveying which platform rules actually fire on
objectstack-ai/hotcrm(its #1621, step 3 of epic #1579). Read-only survey, report-first, unassigned.Measured against the pinned
@objectstack/lint@17.3.0in that app'snode_modules(never the platform source tree), hotcrm at1670557. Every injection was proven to reach disk by blob hash before any conclusion was drawn, and restored by blob hash verified by observation.Fact 1 — a report with no
chartkey is never validated at allvalidate-chart-bindings.tsreaches a report only throughcheckReportChart, which opens:That closure is the only entrance that receives
report.dataset. A report authored without acharttherefore never has its dataset resolved.pipeline_coverage_by_quarter(atype: 'matrix'report that declares nochart),dataset: 'opportunity_metrics'todataset: 'opportunity_metrics_nope'.objectstack lint --jsongivespassed: true,errors: 0, exit 0, no new finding.opportunities_by_stage, which does declare a chart, produceschart-dataset-unknownaterror, exit 1.Fact 2 —
rows/columnsare never checked on any report, charted or notcheckReportChartforwardsvaluesas the measure selection and the two chart axes. The report's dimension selection (rows,columns) is never passed tocheck().opportunities_by_stage,rows: ['stage']torows: ['stage_nope']gives exit 0, no finding.values: ['total_amount', 'avg_probability']tovalues: ['total_amount_nope', 'avg_probability']produceschart-measure-unknownaterrorpluschart-axis-not-selectedatwarning, exit 1.So on one and the same report object, the measure selection is validated and the dimension selection is not.
Consequence
A report bound to a dataset that does not exist, or grouping on a dimension its dataset does not declare, publishes clean —
os lintexits 0 and names nothing. On hotcrm the local testtest/analytics-integrity.test.tscatches both cases, which is how the asymmetry was found; that assertion consequently cannot be retired against these rule ids.Dedupe
Nearest existing cards, both read in full, neither duplicating this:
chart-axis-not-selectedresolves against on the report surface. Same function, different branch; it presumes the chart entrance is taken.Neither addresses the chartless-report entrance or the
rows/columnsomission.