Repository navigation
Read calibration diagnostics schema 9, whose hierarchy labels are declared once in catalogs - #255
Merged
Merged
Conversation
Diagnostics schema 9 declares provider, category, geography and
dimension labels once, in a top-level `hierarchy_catalogs` object, and
each target row refers to them by ID; the target's own label stays on
the row. These tests describe how the dashboard should read it:
- a schema 9 file reads into exactly the rows of the equivalent
schema 8 file, with no label variants, and reports schema version 9
with the hierarchy representation;
- compiled under the recorded schema 8 file's identity, it builds the
recorded UK release tree and reader responses byte for byte;
- release reconciliation publishes a schema 9 release whose uploaded
files equal the schema 8 release's apart from the build ID and the
source digest, which come from the file's bytes;
- a structurally inconsistent file is refused with a message naming the
problem: missing catalogs, an ID listed twice in a catalog or in one
dimension's values, a category whose provider is not listed, a row
that refers to an unknown category, geography, dimension or value
(including a value listed only under another dimension), a row that
lists a dimension twice, a row still in the schema 8 layout, and a
hierarchy target that is not the row's target;
- schema version 9 maps to the hierarchy reader, and 10 is refused.
Test support gains `schema9Diagnostics`, which writes a schema 8
document in the schema 9 layout the way Microcosm's writer will, and
`goldenReleaseRecordFromDocument`, which compiles a recorded release
from another document under the recorded file's identity.
Tests only. Every new test fails because the reader refuses schema 9
("Unsupported calibration diagnostics schema_version 9").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diagnostics schema 9 declares provider, category, geography and dimension labels once, in top-level `hierarchy_catalogs`, and each target row refers to them by ID, so one geography ID or one dimension value ID cannot carry two labels. The target's own label stays on the row, and every other field is the same as in schema 8. `expandHierarchyCatalogs` (new module `hierarchy-catalog-reader`, exported by the package) turns a schema 9 document into a copy whose rows carry the schema 8 hierarchy, with the producer's key order and dimension order, and drops `hierarchy_catalogs`; `schema_version` stays 9. `buildCalibration` applies it before anything reads the targets, so the schema 8 reader, the tree builder, published trees and every route read both versions through the same code. Any other version is passed through as the same object, so schema 8 reading is unchanged. A structurally inconsistent schema 9 file is refused with a message naming the row or catalog entry: missing catalogs or fields, an ID listed twice, a category whose provider is not listed, a reference to an unlisted category, geography, dimension or value (a value is looked up only under its own dimension), a dimension listed twice on one row, a row in the schema 8 layout, or a hierarchy target that is not the row's target. `targetRepresentationForSchema(9)` selects the hierarchy reader. The docs describe the schema 9 layout, the refusals and the reader table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Oct 21, 2026
A schema 9 row's hierarchy holds only catalog references and the target label. Microcosm's schema 9 model and its JSON Schema forbid any other field, but the dashboard reader ignores extra fields, so a row that also carries an inline geography or a dimension value_label (which can only disagree with the catalog) is read using the catalog's label without any error. This test fails now: both documents are accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema 9 reader now refuses a row hierarchy field other than category_id, geography_id, dimensions and target, and a dimension reference field other than id and value_id, as Microcosm's schema 9 model and JSON Schema do. An inline schema 8 label beside a catalog reference could only disagree with the catalog. The check runs after the required fields, so a row still in the schema 8 layout keeps reporting its missing category_id. The refusal list in docs/calibration-map-hierarchy.md names the new case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ma-9-catalogs Brings in #253's two review commits (comments and documentation only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #254
Stacked on #253 (branch
fix/release-reconciliation-continues, head0f8321b), which targetsmain. #253's last commit (test wording only) was merged into this branch (9feb117) rather than rebased, so this branch was never force-pushed. The two changes are independent; this one is chained on #253 only to keep one review stack. Merge #253 first.Companion: PolicyEngine/microcosm#1342 (issue microcosm#1341) makes Microcosm publish schema 9. This PR must be merged and deployed to production before that one merges; that PR says so too.
Problem
Schema 8 copies every provider, category, geography and dimension label onto every target row. Labels come from each source fact (Chronicle packages from different publishers) or from Microcosm builders, and Microcosm only checks that the facts inside one target agree. So one identifier can carry two labels in one published file:
populace-us-2024-buildo-acs-local-766b7c7-20261017T030317Z: 51 states named "Maine" and "ME" under one geography ID (Group calibration tree geographies by geography ID, not label #249, handled in the tree by Group calibration tree geographies by geography ID, not label #250).populace-us-2024-0fb05b6-4b57d15a287c-20260930T150401Z:us:statutes/26/62#adjusted_gross_income/under_1is "No adjusted gross income" on 106 targets and "No adjusted gross income and deficit" on 2 (Calibration tree builder refuses a dimension value that rows label two ways, which stops US release reconciliation #246, handled by Keep the first label spelling in the calibration tree builder instead of refusing rows the reader accepts #247);allandage/85_plushave two spellings too.geography(value IDs are lower-case GSS codes) labelled with each publisher's name. The October 2026 dense release gives 88 areas two names ("Hartlepool UA" / "Hartlepool"); the October national releases give "Yorkshire And The Humber" / "Yorkshire and The Humber". (Measured from the published trees' target detail rows, which carry each row's schema 8 hierarchy.)Design: diagnostics schema 9
Schema 9 is schema 8 with each hierarchy label declared once, in a top-level
hierarchy_catalogsobject, and referred to by ID from the rows. Every other top-level field and every other row field is unchanged.{ "schema_version": 9, "hierarchy_catalogs": { "providers": [{"id": "irs_soi", "label": "IRS Statistics of Income"}], "categories": [{"id": "irs_soi.eitc", "label": "Earned income tax credit", "provider_id": "irs_soi"}], "geographies": [{"id": "0100000US", "label": "United States", "level": "country"}], "dimensions": [{"id": "us:statutes/26/62#adjusted_gross_income", "label": "Adjusted gross income", "values": [{"id": "under_1", "label": "No adjusted gross income"}]}] }, "targets": [{ "name": "irs_soi.eitc.under_1@2024", "target_name": "irs_soi.eitc.under_1", "...": "every other schema 8 field", "hierarchy": { "category_id": "irs_soi.eitc", "geography_id": "0100000US", "dimensions": [{"id": "us:statutes/26/62#adjusted_gross_income", "value_id": "under_1"}], "target": {"id": "irs_soi.eitc.under_1", "label": "EITC returns with no adjusted gross income"} } }] }Decisions:
value_idis looked up under its own dimension, so two dimensions can both have a valueall. A row'sdimensionskeep producer order.hierarchy.providers,hierarchy.categories), and a category names its provider once, so a category under two providers (the one refusal the schema 8 reader keeps) cannot be written at all. A row names only its category.In schema 9 files built from current sources, a geography or dimension value ID cannot carry two labels: Microcosm's writer (companion PR) builds the catalogs from the targets and refuses to write when the rows disagree, unless a reviewed label choice settles it.
Change
hierarchy-catalog-reader.ts(exported as@policyengine/calibration-tree/hierarchy-catalog-reader):expandHierarchyCatalogs(document)turns a schema 9 document into a copy whose rows carry the schema 8 hierarchy, with the producer's key order, and dropshierarchy_catalogs;schema_versionstays 9. Any other version is returned unchanged, as the same object.buildCalibrationapplies it before anything reads the targets. It is the only place in the dashboard that reads the rawtargetsarray (latest-artifact.ts; releases, staging runs, staged bundles and the tree publisher all go through it), so the schema 8 reader, the tree builder, published trees, comparisons and every page read both versions through the same code.targetRepresentationForSchema(9)selects the hierarchy reader; the error for other versions now says "1 through 9".name) or the catalog entry:hierarchy_catalogsor one of its arrays missing, or an entry missing a field; one ID listed twice in a catalog or one value ID twice in a dimension; a category whoseprovider_idis not listed; a row that refers to an unlisted category, geography or dimension, or to a value its own dimension does not list (a value listed only under another dimension); a row that lists one dimension twice or is still in the schema 8 layout; ahierarchy.target.idthat differs fromtarget_name. IDs are compared after trimming whitespace, as the schema 8 reader trims them.docs/calibration-map-hierarchy.md(schema 9 section, reader table, refusals) anddocs/spec-driven-countries.md.Same trees as schema 8
A schema 9 file builds the same tree files as the equivalent schema 8 file without label variants, apart from two identity fields that come from the file's bytes: the build ID and the recorded diagnostics digest.
schema-9-diagnostics.test.ts).publish-calibration-tree.test.ts).0fb05b6(5,694 targets) and766b7c7(4,765), with their label variants rewritten to the first spelling, built as schema 8 and as schema 9 under one identity: all 23 and all 20 bundle files have the same SHA-256. The schema 9 files are about 8% smaller (28.6 MB against 30.9 MB, and 21.5 MB against 23.5 MB, indented as the writer writes them).0fb05b6file (with its US label choices) builds the same 23 files as the schema 8 file with those three values set to the chosen labels.Tests (red, then green)
34c8481schema-9-diagnostics.test.ts(new, 10 tests), a schema 9 publisher test inpublish-calibration-tree.test.ts,target-representation.test.ts(9 is the hierarchy reader, 10 is refused),latest-artifact.test.ts(the unsupported-version loop uses 10 instead of 9). Test support:schema9Diagnosticswrites a schema 8 document in the schema 9 layout, refusing label variants as the writer does;goldenReleaseRecordFromDocumentcompiles a recorded release from another document under the recorded file's identity.bun run lintpasses.e49f7ddbun run lintpassesAt
e49f7dd(and again at9feb117: package 389 pass, typecheck passes):calibration-tree-golden.test.ts12,test-support/calibration-tree-golden-cases.test.ts2,publish-calibration-tree-golden.test.ts7,package-boundary.test.ts9,calibration-tree-artifact.test.ts16,calibration-tree.test.ts41,hierarchy-target-reader.test.ts7,publish-calibration-tree.test.ts21;bun test app lib components scripts(route, library and deploy-check tests): 734 pass, 0 fail;bun run lint(bothtsc --noEmitruns): passes.Consumers of
calibration_diagnostics.json, and schema 9buildCalibration, used by the release, staging, Targets and summary routes, the comparison builders and the tree publisherschema_versionselects the readerdeploy.yml→calibration-deployment-smoke.ts)buildCalibrationonlyevaluation_harness(Python)targets[].metadata.chronicle_record_idscalibration_diagnostics.v8.schema.json)schema_versionconst 8, closed objects)calibration_diagnostics.v9.schema.jsonpolicyengine.py): release certification and dataset materializationcalibration_diagnosticsdeclarationmicrocosm-collectormicrocosm-emitter(open PRs)uk-autumn-budget-dashboard-2026(main and open PR #63)releases.js)target_surface.n_records/n_recordspolicyengine-scorecard(scripts, open PR #53),refundable-credit-conversionanduk-dataset-evaluation(private, scripts run by hand)name,target,final_estimate,relative_error, top-level lossesuk-dataset-evaluation's reduced copy would keephierarchy_catalogspolicyengine-api),policyengine-sim-apiFound with GitHub code search across the organization and by reading each repository above; private Hugging Face repositories and branches other than default and open-PR branches were not checked.
Merge and deploy order
main; each merge deploys production. Confirm production serves this PR before step 3.Environment variables
No workflow, deployment script or configuration changes, and the changed code reads no environment variable.
Notes
diagnostics_schema_version9 and representationhierarchyfor a schema 9 file;hierarchy_label_variantscan list only target-label variants, since the other labels are declared once.🤖 Generated with Claude Code