Skip to content

Regression baseline machinery: portable native baselines + reconstruction-input capture#761

Merged
lewisjared merged 12 commits into
mainfrom
feat/regression-machinery
Jun 29, 2026
Merged

Regression baseline machinery: portable native baselines + reconstruction-input capture#761
lewisjared merged 12 commits into
mainfrom
feat/regression-machinery

Conversation

@lewisjared

@lewisjared lewisjared commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Summary

This branch builds out the portable regression-baseline machinery (native baselines in an object store, reconstruction-input capture, the ref test-cases run/mint/replay/build lifecycle) and includes a round of code-review fixes on top.

The most recent commit (fix(regression): address code-review findings in baseline machinery) addresses findings from a high-effort review of the diff:

Correctness

  • output.json redaction byte-stability — the provenance-redaction re-dump now uses ensure_ascii=False, matching production's pydantic model_dump_json. Previously, any non-ASCII provenance value (e.g. an accented userId) caused the whole file to be re-escaped, breaking the "only redacted fields differ" committed-digest invariant. Verified with a non-ASCII round-trip (only the redacted fields change; no \u escapes).
  • Deterministic PMP output ordering — the plot/data globs in annual_cycle, enso, and variability_modes are now sorted, so the output bundle's keys (and the committed output.json bytes/digest) are filesystem-order independent across hosts.

Cleanup / altitude

  • Extracted _rewrite_committed_json so float-rounding and provenance-redaction share one load/transform/conditional-redump path.
  • Single-sourced the ESMValTool provenance glob (_PROVENANCE_GLOB) so the reconstruction_inputs declaration and the build_execution_result scan can't drift apart.
  • Added a baseline_placeholders(paths, config) factory used by all four ref test-cases verbs, plus a _baseline_placeholders property on RegressionValidator, so the placeholder token set is declared once per context.
  • Coerce CMEC metadata values to strings inside ILAMB's format_cmec_output_bundle rather than patching units at the call site.

Tests

  • Explicitly @pytest.mark.skip the offline test_validate_test_case_regression for all providers. Native baselines now live in the object store, so RegressionValidator cannot rebuild from the committed bundle alone; regression coverage is provided by ref test-cases replay. The test body is retained intact for local step-through debugging.

Parked (not addressed here)

  • Whether RegressionValidator should be deleted or wired to the native store (stage_materialise) so the offline committed-bundle check runs in CI again. The offline tests are skipped for now; the class and its unit tests are retained.
  • Production executor (handle_execution_result) intentionally does not persist reconstruction_inputs — documented as designed.

Verification

  • uv run pre-commit run (ruff check + format, mypy) — all pass.
  • Core regression/testing/output_files/CLI unit suites: 235 passed.
  • PMP/ESMValTool/ILAMB unit suites: pass (2 pre-existing, environment-only test_get_data_path failures unrelated to this branch).
  • test_validate_test_case_regression: 49 explicitly skipped.

https://claude.ai/code/session_01XCLPbjwskcRnJJ3JoQ2Tng

Summary by CodeRabbit

  • New Features
    • Regression baselines can now store additional “reconstruction inputs” so replay can rebuild missing native outputs for greater reproducibility.
    • Captures can include extra matched files via configurable globs, improving completeness of stored artefacts.
  • Bug Fixes
    • Improved portability and determinism for captured/replayed artefacts, including stable digests, deterministic auxiliary output discovery, byte-stable float rounding, provenance redaction, and consistent unit handling as strings.
  • Tests
    • Expanded unit and integration coverage for replay inputs, placeholder portability/hydration, provenance redaction, and native snapshot stability.
  • Documentation
    • Updated guidance for replay and baseline behaviour.

…pture

Make committed regression baselines reproducible from their stored native
blobs on any machine and provider, so `ref test-cases replay` and the
coupling gate stop reporting spurious drift.

Two layers:

1. Port the PlaceholderMap path machinery (from #759/#756): a single
   bidirectional map (`<OUTPUT_DIR>` / `<TEST_DATA_DIR>` /
   `<SOFTWARE_ROOT_DIR>`) drives capture sanitise, replay hydrate and the
   comparator, sourcing the software root from `config.paths.software`;
   plus `<USER>`/`<DATE>` provenance redaction in the committed bundle.

2. Capture reconstruction inputs and store native portably:
   - `copy_execution_outputs(..., extra_globs=)` persists extra declared
     globs beyond the bundle-referenced files (deduped, directories skipped).
   - new `Diagnostic.reconstruction_inputs` declares the raw artefacts a
     provider's `build_execution_result` re-scans (provenance YAML, driver
     `*_cmec.json`) that the curated set would otherwise exclude.
   - `snapshot_native` sanitises the slot to placeholders before digesting,
     so native digests are machine-independent (re-mint uploads nothing) and
     replay can hydrate the blobs anywhere -- load-bearing now that the
     captured provenance/cmec files are path-bearing.

Rebuild stays on `build_execution_result`, so a replay re-derives the bundle
from the captured inputs (option 2) rather than from an incomplete output dir.

Tests: extra_globs behaviour, snapshot portability incl. `<SOFTWARE_ROOT_DIR>`
and machine-independent digests, and a reconstruction-input round-trip proving
replay rebuilds from a captured provenance file (positive) and fails without it
(negative).

Constraint: native blobs must stay machine-independent or re-mints churn the store
Constraint: capture_execution writes the production results dir, so native is only sanitised in the throwaway output slot, never in place there
Rejected: option 1 (rebuild from committed output.json) | neuters replay's ability to catch build_execution_result regressions
Directive: a provider declaring reconstruction_inputs must also ensure build_execution_result is deterministic under replay (stable session dir; idempotent in-place mutations like pmp clean_up_json)
Confidence: high
Scope-risk: moderate
Not-tested: real esmvaltool/pmp providers (no reconstruction_inputs declared yet; needs conda + baseline data)

Claude-Session: https://claude.ai/code/session_01XCLPbjwskcRnJJ3JoQ2Tng
Wire up the providers to the reconstruction-input capture so their committed
baselines can be rebuilt from the persisted native set on replay.

- esmvaltool: persist `executions/recipe/run/*/*/diagnostic_provenance.yml`,
  the raw provenance `build_execution_result` globs to discover the run's
  outputs. The existing `prepare_regression_output` already stabilises the
  timestamped session dir to `recipe` and every path the provenance holds is
  under the execution output dir, so native sanitisation makes it portable.
- pmp: persist the raw driver `*_cmec.json` that `process_json_result`
  consumes, declared once as `PMP_RECONSTRUCTION_INPUTS` in `pmp_driver` and
  shared by the three diagnostics (variability-modes, annual-cycle, enso).

Tests: an esmvaltool capture -> sanitise -> hydrate -> rebuild round-trip
proving the provenance is captured and the bundle rebuilds from it, and a pmp
test pinning the declaration and that the glob matches the driver's CMEC JSON
naming (mip-scoped and plain) but not the curated bundle.

Constraint: pmp clean_up_json mutates the raw cmec.json in place during build; it runs before capture and is byte-idempotent on an already-cleaned file, so the capture->replay round-trip is stable
Confidence: high
Scope-risk: narrow
Not-tested: full esmvaltool/pmp mint+replay end-to-end (needs conda + baseline data; validated via unit round-trips and the generic reconstruction-input test instead)

Claude-Session: https://claude.ai/code/session_01XCLPbjwskcRnJJ3JoQ2Tng
…eview

Two quality fixes from the /simplify pass (no behaviour change):

- `snapshot_native` now takes `source` + an unbound `PlaceholderMap` and binds
  `with_output(source.bundle_output_dir)` internally, matching `stage_build`'s
  signature. Callers no longer pre-bind the map, so the two stages can't drift on
  which output directory they sanitise.
- `_copy_extra_globs` takes an `exclude` set and owns all dedup, replacing the
  split copy/append-with-membership-check in `copy_execution_outputs`.

Confidence: high
Scope-risk: narrow

Claude-Session: https://claude.ai/code/session_01XCLPbjwskcRnJJ3JoQ2Tng
Correctness:
- Re-dump output.json provenance redaction with ensure_ascii=False so it matches
  production's pydantic model_dump_json; non-ASCII provenance no longer rewrites
  the whole file, preserving the "only redacted fields differ" committed-digest
  invariant.
- Sort the PMP plot/data globs (annual_cycle, enso, variability_modes) so the
  output bundle's keys -- and the committed output.json bytes/digest -- are
  filesystem-order independent and reproducible across hosts.

Cleanup / altitude:
- Extract _rewrite_committed_json so float-rounding and provenance-redaction share
  one load/transform/conditional-redump path instead of two clones.
- Single-source the ESMValTool provenance glob (_PROVENANCE_GLOB) so the
  reconstruction_inputs declaration and build_execution_result scan cannot drift.
- Add baseline_placeholders() factory used by run/mint/replay/build, and a
  _baseline_placeholders property on RegressionValidator, so the placeholder token
  set is declared once per context.
- Coerce CMEC metadata values to strings inside ILAMB's format_cmec_output_bundle
  rather than patching units at the call site.

Tests:
- Explicitly @pytest.mark.skip the offline test_validate_test_case_regression for
  all providers. Native baselines now live in the object store (Framework B), so
  RegressionValidator cannot rebuild from the committed bundle alone; regression
  coverage is provided by `ref test-cases replay`. The test body is retained for
  local step-through debugging.

Constraint: Native baselines are object-store-only, so the committed-bundle replay
  path cannot run offline without sharing stage_materialise into the test.
Rejected: Delete RegressionValidator | kept for local step-through debugging per
  maintainer request; migration intent not yet reconciled.
Rejected: Wire the native store into RegressionValidator | larger architectural
  change, parked.
Confidence: high
Scope-risk: moderate
Not-tested: PMP/ESMValTool committed-bundle rebuild (no committed catalog; skipped)
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds PlaceholderMap-driven capture and replay plumbing for regression baselines, persists extra reconstruction inputs, redacts provenance fields in committed bundles, and updates ESMValTool, PMP, ILAMB, and test-case flows to use deterministic output selection and replayable native artefacts.

Changes

Portable regression baseline replay

Layer / File(s) Summary
Placeholder and copy contracts
changelog/761.fix.md, packages/climate-ref-core/src/climate_ref_core/diagnostics.py, packages/climate-ref-core/src/climate_ref_core/output_files.py, packages/climate-ref-core/tests/unit/test_output_files.py
Diagnostic.reconstruction_inputs and PlaceholderMap replace the placeholder helpers, add optional software-root binding and extra-glob copying, and the unit tests cover sanitise/hydrate, replacement maps, output binding, and copy behaviour.
Committed bundle capture
packages/climate-ref-core/src/climate_ref_core/regression/capture.py, packages/climate-ref-core/tests/unit/regression/test_capture.py
Committed bundles now take an output-bound PlaceholderMap, are sanitised before float rounding and provenance redaction, and capture_execution carries extra_globs through to output copying; the tests cover those capture and redaction paths.
Replay, build, and snapshot flow
packages/climate-ref-core/src/climate_ref_core/testing.py, packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py, packages/climate-ref/src/climate_ref/cli/test_cases/baselines.py, packages/climate-ref/src/climate_ref/cli/test_cases/run.py, packages/climate-ref/tests/integration/test_native_roundtrip.py, packages/climate-ref/tests/unit/cli/test_test_cases.py
Regression validation and test-case lifecycle verbs now build and bind PlaceholderMap values through replay, mint, build, and snapshot paths, including reconstruction_inputs capture and replay hydration; integration and snapshot tests exercise the new round-trip.
Provider replay inputs and bundle normalisation
packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/base.py, packages/climate-ref-esmvaltool/tests/integration/test_diagnostics.py, packages/climate-ref-esmvaltool/tests/unit/diagnostics/test_base.py, packages/climate-ref-pmp/src/climate_ref_pmp/pmp_driver.py, packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/annual_cycle.py, packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/enso.py, packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/variability_modes.py, packages/climate-ref-pmp/tests/integration/test_diagnostics.py, packages/climate-ref-pmp/tests/unit/test_pmp_driver.py, packages/climate-ref-ilamb/src/climate_ref_ilamb/standard.py, packages/climate-ref-ilamb/tests/integration/test_diagnostics.py
ESMValTool and PMP diagnostics declare reconstruction-input globs and gather outputs deterministically, while ILAMB stringifies CMEC metadata values consistently; the related tests are skipped or expanded around the new replay path.

Possibly related PRs

  • Climate-REF/climate-ref#744: Both PRs change committed regression-bundle byte-stabilisation by modifying climate_ref_core/regression/capture.py’s float-rounding and JSON rewrite flow.
  • Climate-REF/climate-ref#748: This PR extends the same ref test-cases stage pipeline with PlaceholderMap, reconstruction_inputs, and replay capture changes.
  • Climate-REF/climate-ref#755: Both PRs touch packages/climate-ref-ilamb/src/climate_ref_ilamb/standard.py to coerce CMEC metadata values to strings during bundle construction.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.95% 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 succinctly captures the main change: portable regression baselines plus reconstruction-input capture.
Description check ✅ Passed It covers the summary, tests, verification, and changelog notes, though the template's explicit checklist is not formatted as requested.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/regression-machinery

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

@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.38462% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ef-core/src/climate_ref_core/regression/capture.py 89.18% 2 Missing and 2 partials ⚠️
...te-ref-pmp/src/climate_ref_pmp/diagnostics/enso.py 40.00% 3 Missing ⚠️
...mp/src/climate_ref_pmp/diagnostics/annual_cycle.py 33.33% 2 Missing ⚠️
...te-ref/src/climate_ref/cli/test_cases/baselines.py 88.88% 1 Missing ⚠️
Flag Coverage Δ
core 92.60% <94.04%> (+0.06%) ⬆️
providers 85.47% <75.00%> (+0.01%) ⬆️

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

Files with missing lines Coverage Δ
...imate-ref-core/src/climate_ref_core/diagnostics.py 97.33% <100.00%> (+0.01%) ⬆️
...ate-ref-core/src/climate_ref_core/esgf/registry.py 85.55% <ø> (ø)
...mate-ref-core/src/climate_ref_core/output_files.py 100.00% <100.00%> (ø)
...-core/src/climate_ref_core/regression/_quantise.py 100.00% <ø> (ø)
...s/climate-ref-core/src/climate_ref_core/testing.py 89.73% <100.00%> (+0.11%) ⬆️
...ool/src/climate_ref_esmvaltool/diagnostics/base.py 89.44% <100.00%> (+0.26%) ⬆️
...limate-ref-ilamb/src/climate_ref_ilamb/standard.py 82.10% <100.00%> (ø)
...c/climate_ref_pmp/diagnostics/variability_modes.py 89.09% <100.00%> (+0.20%) ⬆️
.../climate-ref-pmp/src/climate_ref_pmp/pmp_driver.py 78.40% <ø> (ø)
...mate-ref/src/climate_ref/cli/test_cases/_stages.py 94.06% <100.00%> (+0.15%) ⬆️
... and 6 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/climate-ref/tests/integration/test_native_roundtrip.py (1)

303-309: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

capture_execution() still looks host-specific for native digests.

This helper now passes a bound PlaceholderMap, but the shared implementation in packages/climate-ref-core/src/climate_ref_core/regression/capture.py:328-388 still snapshots base_dir straight after copy_execution_outputs(...) and never sanitises the copied tree first. That leaves native blobs authored via this path sensitive to absolute host paths, so these round-trip tests can miss the digest-churn bug this PR is meant to prevent.

Possible fix in packages/climate-ref-core/src/climate_ref_core/regression/capture.py
     relpaths = copy_execution_outputs(
         scratch_directory,
         results_directory,
         fragment,
         result,
         include_log=include_log,
         extra_globs=extra_globs,
     )
     base_dir = results_directory / fragment
     committed = write_committed_bundle(base_dir, regression_dir, placeholders=placeholders)
+    placeholders.sanitise(base_dir)
     native = build_native_snapshot(base_dir, relpaths)
     return committed, native
🧹 Nitpick comments (2)
packages/climate-ref/tests/integration/test_native_roundtrip.py (1)

394-395: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the same PlaceholderMap for replay comparisons.

These tests now hydrate with PlaceholderMap, but the later replacements mapping is still hand-rolled. If <SOFTWARE_ROOT_DIR> ever appears in the rebuilt bundle, the comparison path drifts from capture again. Please derive the replacements from the same map via .with_output(replay_dir).as_replacements().

Also applies to: 594-595

packages/climate-ref-esmvaltool/tests/integration/test_diagnostics.py (1)

26-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the parked offline regression path opt-in, not permanently skipped.

An unconditional @pytest.mark.skip means this body is not actually available for local step-through debugging unless someone edits the test file. A skipif behind an env var or pytest option would keep CI parked while preserving the debug path you describe here. The same applies to the matching skip added in the other provider integration suites.

Example pattern
+import os
+
-@pytest.mark.skip(
+@pytest.mark.skipif(
+    not os.getenv("REF_ENABLE_OFFLINE_REGRESSION_DEBUG"),
     reason="Parked: RegressionValidator replays the committed bundle offline, but native baselines "
     "now live in the object store (Framework B), so build_execution_result cannot rebuild from the "
     "repo alone. `ref test-cases replay` provides regression coverage via the store; this offline "
     "path is retained (body intact) for local step-through debugging."
 )

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1fcd1905-89f5-4ee8-bf2e-5aaefd3a3bc8

📥 Commits

Reviewing files that changed from the base of the PR and between 7048752 and 67973f9.

📒 Files selected for processing (24)
  • changelog/761.fix.md
  • packages/climate-ref-core/src/climate_ref_core/diagnostics.py
  • packages/climate-ref-core/src/climate_ref_core/output_files.py
  • packages/climate-ref-core/src/climate_ref_core/regression/capture.py
  • packages/climate-ref-core/src/climate_ref_core/testing.py
  • packages/climate-ref-core/tests/unit/regression/test_capture.py
  • packages/climate-ref-core/tests/unit/test_output_files.py
  • packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/base.py
  • packages/climate-ref-esmvaltool/tests/integration/test_diagnostics.py
  • packages/climate-ref-esmvaltool/tests/unit/diagnostics/test_base.py
  • packages/climate-ref-example/tests/integration/test_diagnostics.py
  • packages/climate-ref-ilamb/src/climate_ref_ilamb/standard.py
  • packages/climate-ref-ilamb/tests/integration/test_diagnostics.py
  • packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/annual_cycle.py
  • packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/enso.py
  • packages/climate-ref-pmp/src/climate_ref_pmp/diagnostics/variability_modes.py
  • packages/climate-ref-pmp/src/climate_ref_pmp/pmp_driver.py
  • packages/climate-ref-pmp/tests/integration/test_diagnostics.py
  • packages/climate-ref-pmp/tests/unit/test_pmp_driver.py
  • packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
  • packages/climate-ref/src/climate_ref/cli/test_cases/baselines.py
  • packages/climate-ref/src/climate_ref/cli/test_cases/run.py
  • packages/climate-ref/tests/integration/test_native_roundtrip.py
  • packages/climate-ref/tests/unit/cli/test_test_cases.py

Per code review: provenance redaction scrubbed userId/date but left the nested
`platform` block intact. Real PMP provenance records `platform.Name` (the minting
hostname, e.g. "gus") and `platform.Version` (the kernel version) — both leak host
identity into the git-tracked bundle and churn its committed digest across machines,
defeating the portability goal. Redact them to <HOSTNAME>/<HOST_VERSION>; keep the
coarse `OS` value as portable context. Extracts a `_redact_fields` helper so the
provenance and platform sub-blocks share one set-if-present-and-changed loop, and
strengthens test_write_committed_bundle_redacts_and_placeholders_provenance to assert
the host fields no longer survive.

No committed baseline leaks today (PMP, the only provenance-bearing provider, has no
committed regression bundles yet), so this hardens the redaction before those land.

Constraint: redaction must change only the targeted fields to keep the committed
  digest reproducible at mint and replay.
Confidence: high
Scope-risk: narrow
Drop comments that restated the code (e.g. "Find the other outputs") and tighten
the rest to the part that isn't obvious: why the PMP globs are sorted (deterministic
committed output.json digest), why output.json re-dumps with ensure_ascii=False, why
platform host fields are redacted while OS is kept, and why ILAMB coerces metadata to
str. Comment-only; no behaviour change.
@lewisjared lewisjared force-pushed the feat/regression-machinery branch from 6c8148f to 013fd18 Compare June 27, 2026 06:14
@lewisjared

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Replace the per-file maps (_COMMITTED_FLOAT_JSON_KWARGS / _UNROUNDED_COMMITTED_FILES
/ _PROVENANCE_BEARING_FILES / _COMMITTED_DUMP_KWARGS) and their round/redact/rewrite
helpers with a single pass: every committed JSON file is float-rounded, provenance-
redacted, and re-dumped with one canonical format (sort_keys, indent, allow_nan=False,
ensure_ascii=False). A file with no floats or no provenance just passes those steps
through, so output.json no longer needs a special "unrounded, preserve native order"
case. The bundle comparator is structural (compares dict key sets, not bytes), so
sorting output.json keys is safe and makes the committed bytes fully deterministic.

Net ~130 fewer lines; the serialisation rule now lives in one constant instead of
four filename-keyed maps.

Note: output.json is now sorted/canonical, so existing committed baselines should be
re-minted to match; the tolerant replay comparison reconciles them until then.

Constraint: committed bytes must be identical at mint and replay across machines.
Confidence: high
Scope-risk: moderate
@lewisjared lewisjared merged commit 72f0888 into main Jun 29, 2026
28 checks passed
@lewisjared lewisjared deleted the feat/regression-machinery branch June 29, 2026 03:29
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