Skip to content

Carry dimension and value labels on consumer facts (dimension_labels, dimension_value_labels, layout.groupby_dimension_label) so microcosm's hierarchy compiles from the artifact #261

Description

@juaristi22

Microcosm's calibration hierarchy (microcosm#855, schema 8, merged 2026-09-11) completes every target's hierarchy from the Chronicle facts it selects and now requires each fact to carry human labels for every dimension and every dimension value. The consumer artifact does not carry them, so tools/generate_uk_target_references.py fails on every real feed, old and new alike:

LedgerHierarchyMetadataError: Ledger target reference 'obr.income_tax': Chronicle fact
'ledger.aggregate_fact.v2:d928e7da0fbfe088ca1a30d7' dimension 'obr.efo_line' requires exactly one
non-empty label, got [].

Microcosm will take a fallback in the meantime; this issue is the durable fix: Chronicle owns the labels, so the artifact should carry them.

What the consumer reads

From microcosm/build/ledger_targets.py (_validate_chronicle_hierarchy_labels, _inherited_dimensions, _dimension_label, _dimension_value_label), per fact:

  • label — already present; must be non-empty.
  • dimension_labels — a mapping dimension_id -> label covering every key of dimensions and, when layout.groupby_dimension is set, that id too (Microcosm folds layout.groupby_dimension: layout.groupby_value_id into the dimension set when the key is absent from dimensions).
  • dimension_value_labels — a nested mapping dimension_id -> value_id -> label, where value_id is the string form of the dimension value (str(value); booleans lower-cased; lists and mappings JSON-serialised with sorted keys and no spaces).
  • layout.groupby_dimension_label — accepted as the label of the groupby dimension in place of a dimension_labels entry; layout.groupby_value_label (already emitted) is accepted as the value label of the groupby value.

Labels must be identical across every fact a target selects; conflicting labels are refused.

Examples of what is missing today: the OBR EFO rows carry layout.groupby_dimension: obr.efo_line and layout.groupby_value_label: "Income tax (gross of tax credits)" but no label for obr.efo_line itself; the UC crosses from #260 carry dimensions: {carer_entitlement: "No", payment_indicator: "Yes"} and layout.groupby_dimension: dwp.carer_entitlement with no label for carer_entitlement, payment_indicator or dwp.carer_entitlement, and no per-dimension value labels (the row label "No, Yes" is the combined groupby value).

Ask

  1. Emit dimension_labels, dimension_value_labels and layout.groupby_dimension_label on every consumer fact.
  2. Source the labels from Chronicle-owned declarations, not from identifiers: the Stat-Xplore field labels the archived responses already carry ("Carer Entitlement", "Payment Indicator", "Housing Entitlement - Tenure"), the recode item labels for values ("Yes", "No", "Social Rented Sector"), publisher line labels for the OBR / HMRC tables, and a package-level dimension_labels block in source_package.yaml for anything the parser cannot recover, with a bundle check that every dimension id and value in a package has exactly one label.
  3. Version it: consumer_fact.v1 declares additionalProperties: false, so the additive keys need consumer_fact.v2 (epoch.py already reserves chronicle.consumer_fact.v2). Microcosm pins consumer_fact_schema_sha256 and the accepted schema-version list in uk/national_chronicle_feed.json, so the pin moves in the same re-pin that adopts the new artifact; the facts, keys and values must not change.
  4. Cover the UK suite completely (every groupby_dimension and every dimensions key in the bundle), since Microcosm validates every selected fact, not only the new ones.

Context

  • Consumer-side mechanism and the interim fallback: microcosm issue to follow from the draft uk-855-generator-regression-issue-draft.md (microcosm#855, #854).
  • Blocked consumers today: microcosm#882's element bindings (branch uk-uc-elements-882, on the 9f8b77af artifact), microcosm#904 and #906 once they rebase onto main.
  • Not asked: changes to fact values, keys, periods, geographies or the record-set ids.

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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions