Skip to content

Receipts: the base's own grid record (diff.base_events) and staging's grid lists - #183

Draft
MaxGhenis wants to merge 1 commit into
w6/ab2025-eventfrom
w6/receipt-base-events
Draft

MaxGhenis wants to merge 1 commit into
w6/ab2025-eventfrom
w6/receipt-base-events

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

Stacked on #175. Merge #175 first, then this with a merge commit.

Draft until CI passes and an independent review agrees. The local full suite passes: 1,848 passed, 15 skipped.

W4's replay gate (d1344 decision record, agreed with W4 on 2026-10-15) counts a candidate gap as known only when there is positive evidence that the base had the same pair. Today a receipt can't show that: full_supported_grid_complete covers both inert and missing pairs, and diff flags can't prove the base's state. This adds the base side's own record.

Receipt changes

All additive and optional. Receipts already issued stay valid; the golden fixture is unchanged and still validates.

diff.base_events.<event> — the base namespace's grid record:

  • staging_manifest_sha256 and run_manifest_sha256;
  • supported_years, taken from the base's RUN_MANIFEST.json, because staging does not record supported years (the receipt's own corpus block already reads them from there);
  • full_supported_grid_complete;
  • inert_measure_years, always present, [] when there are none;
  • missing_measure_years and unsupported_measure_years, with staging's names and meanings.

How it is read:

  • Source: the base's STAGING_MANIFEST.json and RUN_MANIFEST.json, bound to the digests DIFF.json recorded for them. The receipt step fails if the files differ.
  • When there is no entry: the base staging predates the variant grid fields (the legacy layout), or the base did not replay the event. A base gap is reported only from the base's own manifests, never inferred.
  • Meanings:
    • a missing pair is in the full event grid but has no artifact, so the list includes unsupported pairs;
    • a supported-grid gap is a missing pair that is not unsupported;
    • W4's test pairs a candidate's inert or (missing − unsupported) pair with the same pair in the base's lists.

corpus.events.<event> now also carries staging's missing_measure_years and unsupported_measure_years, so W4 matches candidate pairs directly.

Schema: docs/uk_replay/schemas/replay_receipt.v1.json gains $defs.measure_years (now also used by inert_measure_years), $defs.base_event, the two optional corpus fields and the optional diff.base_events. QUALIFICATION_INTERFACE.md documents each field and when it is absent.

Invariants

  • Digest binding: a base_events entry exists exactly when the base staging has full_supported_grid_complete and both grid lists (property-tested). Its digests equal those DIFF.json recorded.
  • Verbatim lists: its lists are the staging manifest's, unchanged (property-tested).
  • No inference: no entry is ever synthesized, for a legacy base, a missing event, or a diff without inputs.

Checks run

  • Tests:
    • base record values and digest binding; refusal on a changed staging or run manifest;
    • no entry without the grid fields or the inputs;
    • diff_summary carries the record, and event_results carries the lists (legacy-shaped staging gets none);
    • the schema accepts the new fields, refuses a base record missing any field, and refuses a malformed pair.
  • Mutation: each mutant fails at least one test: no digest binding, an entry without the fields, supported years from staging, inert_measure_years omitted, no candidate lists, and a summary without base_events.
  • Suite: full suite and ruff format --check pass.

W4 vendors the schema change from this PR's head.

axiom: n/a: replay receipt format; no policy encoding.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
policyengine-scorecard Ready Ready Preview Oct 15, 2026 8:41pm UTC

Request Review

… grid lists

For W4's replay gate (d1344 decision record, agreed 2026-10-15): a candidate
gap is known only on positive evidence that the base had the same pair.

- The release diff records, per side, each event's grid as that side's
  verified staging recorded it (DIFF.json base/head `grids`,
  diff_uk_event_runs.staging_grid): supported_years from the run manifest
  (staging does not record them), full_supported_grid_complete,
  inert_measure_years (always present), and staging's missing and
  unsupported measure-years with staging's meanings. Variant runs only: a
  legacy-layout run has no grid, so no gap is ever inferred for it.
- diff.base_events copies the base side's grids from DIFF.json, with the
  staging and run manifest digests the diff recorded; diff_sha256 binds it
  and nothing is re-read. A requalified certified pair's base and
  candidate share one result root, so a second read from the receipt's
  checkout would have read the candidate (review of e4dee5e).
- Each corpus event carries staging's missing and unsupported lists too.
- Schema: additive and optional; a shared measure_years definition with
  unique pairs and non-empty keys.

Tests: staging_grid values and the legacy gate; a property test that
base_events copies the grid verbatim with unsupported a subset of missing
(a swap fails); an integration test where base and candidate share a root
and differ; event_results lists; schema acceptance and refusals. Mutants
(swaps in staging_grid and event_results, no variant gate, base_events from
the head, no recorded grid) each fail a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — cb8d33fb Deployed Oct 15, 2026 by vercel[bot]
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