Skip to content

lint: validateChartBindings never checks a report without a chart — a chartless report's dataset is unvalidated, and rows/columns are unvalidated on every report #16105

Description

@os-steve

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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions