Skip to content

feat(core): add kind, reference_id and typed presentation attrs to metric values#772

Merged
lewisjared merged 4 commits into
mainfrom
feat/layer-a-core-contract
Jun 30, 2026
Merged

feat(core): add kind, reference_id and typed presentation attrs to metric values#772
lewisjared merged 4 commits into
mainfrom
feat/layer-a-core-contract

Conversation

@lewisjared

@lewisjared lewisjared commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

This establishes a way of distinguishing model and reference values and for carrying typed presentation metadata.

This PR adds:

  • kind ("model" / "reference") field on the SeriesMetricValue and ScalarMetricValue. It defaults to "model", so existing producers are unaffected.
  • A reference_id content hash on series, computed and stored at ingest for reference values, so an identical observation ingested by different executions deduplicates to the same id.
  • Typed, optional presentation fields on series (value_units, value_long_name, index_units, calendar) that fall back to the existing attributes dict when absent. These stay optional until every provider emits them.
  • Checks for kind at ingest.

Adds a DB migration.

Checklist

Please confirm that this pull request has done the following:

  • Tests added
  • Documentation added (where applicable)
  • Changelog item added to changelog/

Summary by CodeRabbit

  • New Features

    • Metric values now distinguish between model and reference data.
    • Reference series can be tracked with a stable identifier, helping match identical observations across runs.
    • Series metadata can now include units, long names, index units, and calendar details.
  • Bug Fixes

    • Improved validation for metric value roles during import.
    • Preserved consistent ordering and output for metric data, reducing unexpected changes in saved results.

…tric values

Establish the core metric-value contract that later work builds on, without
changing any provider output.

- Add a first-class `kind` ("model"/"reference") field to the core
  `SeriesMetricValue` and `ScalarMetricValue` models, registered as a
  controlled-vocabulary dimension so it becomes a faceted column.
- Add a `reference_id` content hash to series, computed and stored at ingest
  for reference values, so identical observations deduplicate deterministically.
- Add typed, optional presentation fields (`value_units`, `value_long_name`,
  `index_units`, `calendar`) on series, falling back to `attributes` when absent.
- Reject an unknown `kind` hard at ingest rather than warning.
- Add a migration for the `reference_id` column (`kind` auto-adds via the
  existing CV dimension mechanism).
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a58ed59a-b3ba-4018-9d9e-e87b0a31e13a

📥 Commits

Reviewing files that changed from the base of the PR and between 9f53cf2 and 8ed2384.

📒 Files selected for processing (2)
  • packages/climate-ref-core/src/climate_ref_core/metric_values/typing.py
  • packages/climate-ref/src/climate_ref/migrations/versions/2026-06-30T0000_e5f6a7b8c9d0_add_reference_id.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/climate-ref/src/climate_ref/migrations/versions/2026-06-30T0000_e5f6a7b8c9d0_add_reference_id.py

📝 Walkthrough

Walkthrough

Adds MetricValueKind to metric values, adds reference_id for reference series, validates kind during ingestion, updates the storage model and migration, and adds tests plus a changelog entry.

Changes

MetricValueKind and reference_id

Layer / File(s) Summary
Metric value contracts
packages/climate-ref-core/src/climate_ref_core/metric_values/typing.py, packages/climate-ref-core/src/climate_ref_core/metric_values/__init__.py, packages/climate-ref-core/src/climate_ref_core/pycmec/cv_cmip7_aft.yaml
Defines MetricValueKind, adds kind and reference_id to series values, adds presentation metadata fields, adds kind to scalar values, re-exports MetricValueKind, and registers the kind dimension in the CMEC CV schema.
Reference hashing and column
packages/climate-ref/src/climate_ref/models/metric_value.py
Adds _content_hash, refactors SeriesIndex.compute_hash, adds the reference_id ORM column, and implements compute_reference_id from series payload parts.
Database migration
packages/climate-ref/src/climate_ref/migrations/versions/2026-06-30T0000_e5f6a7b8c9d0_add_reference_id.py
Adds the Alembic migration that creates the nullable reference_id column and index on metric_value, with matching downgrade steps.
Kind validation and reference persistence
packages/climate-ref/src/climate_ref/executor/result_handling.py
Adds _VALID_KINDS and _validated_kind_and_dimensions, validates scalar and series ingestion kinds, stores validated dimensions, and computes reference_id for reference series.
Type and ingestion tests
packages/climate-ref-core/tests/unit/metric_values/test_typing.py, packages/climate-ref/tests/unit/executor/test_result_handling.py
Adds tests for kind defaults and validation, presentation-field round-tripping, ingestion-time kind persistence, invalid kind rejection, and deterministic reference_id assignment.
Changelog entry
changelog/772.feature.md
Documents the new kind field, stable reference_id, and typed presentation metadata fields.

Possibly related PRs

  • Climate-REF/climate-ref#747: Modifies the same SeriesIndex.compute_hash and ingest_series_values code paths in metric_value.py and result_handling.py, adding index_axis/index_id where this PR adds kind/reference_id.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately reflects the main changes to metric value kinds, reference IDs, and typed presentation fields.
Description check ✅ Passed The description includes the required sections and covers the main changes and checklist items, with only non-critical documentation left unchecked.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/layer-a-core-contract

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 940a820e-5da4-4810-9387-f3eaefd387db

📥 Commits

Reviewing files that changed from the base of the PR and between b236908 and 9f53cf2.

📒 Files selected for processing (9)
  • changelog/772.feature.md
  • packages/climate-ref-core/src/climate_ref_core/metric_values/__init__.py
  • packages/climate-ref-core/src/climate_ref_core/metric_values/typing.py
  • packages/climate-ref-core/src/climate_ref_core/pycmec/cv_cmip7_aft.yaml
  • packages/climate-ref-core/tests/unit/metric_values/test_typing.py
  • packages/climate-ref/src/climate_ref/executor/result_handling.py
  • packages/climate-ref/src/climate_ref/migrations/versions/2026-06-30T0000_e5f6a7b8c9d0_add_reference_id.py
  • packages/climate-ref/src/climate_ref/models/metric_value.py
  • packages/climate-ref/tests/unit/executor/test_result_handling.py

Comment thread packages/climate-ref/src/climate_ref/executor/result_handling.py
Comment thread packages/climate-ref/src/climate_ref/models/metric_value.py
…mn type

- Omit the newly added series fields (`kind`, `reference_id`, and the typed
  presentation fields) from the serialised series.json when they are at their
  default, so a value that does not set them serialises identically to one from
  before the fields existed. This keeps the committed regression baselines valid
  without a re-mint (replay drift), while still serialising the fields when set.
- Include `kind` in the deterministic series sort key, since it now identifies a
  value outside `dimensions`.
- Declare the `reference_id` migration column as String to match the model, so
  the migrations-up-to-date check no longer reports a spurious type diff.
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
core 92.34% <100.00%> (+0.03%) ⬆️
providers 86.29% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ore/src/climate_ref_core/metric_values/__init__.py 100.00% <100.00%> (ø)
...-core/src/climate_ref_core/metric_values/typing.py 95.50% <100.00%> (+1.65%) ⬆️
...te-ref/src/climate_ref/executor/result_handling.py 96.03% <100.00%> (+0.49%) ⬆️
...climate-ref/src/climate_ref/models/metric_value.py 93.75% <100.00%> (+0.49%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lewisjared lewisjared merged commit cc8ac3d into main Jun 30, 2026
28 checks passed
@lewisjared lewisjared deleted the feat/layer-a-core-contract branch June 30, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant