Skip to content

Add an artifact diff command so a deliberate refresh is compared value by value #58

Description

@ChelseaKR

What

A refresh of the pinned retrievals replaces site/data/perimeters-coverage.json and site/data/dins-coverage.json wholesale, and today the only thing that says what moved is git diff over a large JSON document. python -m perimeter.diff OLD.json NEW.json walks every leaf of both artifacts, reports each changed value with its path, old value and new value, reports keys added, and refuses to pass when a published key disappeared unless --allow-removals names that as deliberate. Output is console and --json; exit 0 no change, 1 changes reported, 2 removals not allowed or unreadable input. make site-check prints the diff when the served artifact and a fresh build disagree.

Why it matters

The README promises figures "move only when those retrievals are deliberately refreshed", and a deliberate refresh should be able to say what it moved. The sibling wildfire-service-territory-overlap built exactly this (artifact_diff.py) and used it to show a 4,370-value comparison with nothing removed; perimeter is its upstream and should hold itself to the same discipline. The command is offline, deterministic, and reads only the two files given. A field moving from a number to null (a domain the layer stopped publishing, per ADR-0010) is reported as a change to absence, not as a removal.

Scope

  • src/perimeter/diff.py and a make diff OLD=... NEW=... target; --allow-removals, --json, --ignore is_fixture for comparing a fixture build to itself.
  • Leaf comparison with integer-exact equality; tenths_pct fields compared as integers, never as floats.
  • A comparison artifact ({path, old, new} rows sorted by path) that PROVENANCE.md can cite for a refresh.
  • Tests over artifacts that must fail it (a removed key, a changed count, a type change, an empty file), per ADR-0004.

Out of scope

  • Diffing the pages; they are rendered from the artifacts.
  • Automatic refreshes.

Done when

  • Diffing an artifact against itself exits 0 and prints "no change".
  • Removing duplicate_signals from the new artifact exits 2 without --allow-removals and 1 with it, naming the key.
  • A records count change is reported with both values, and the JSON output is byte-identical on repeat.
  • make site-check on a deliberately altered site/data/ prints the leaf-level diff.

Pointers

  • src/perimeter/artifacts.py, cli.py, Makefile (site-check), PROVENANCE.md
  • wildfire-service-territory-overlap: src/wildfire_service_territory_overlap/artifact_diff.py, tests/test_artifact_diff.py

Proposed with AI assistance.

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

    enhancementNew feature or requestfeatureMajor new capability proposal

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions