Repository navigation
Audit period strips by reviewed template, not an exact spelling list - #309
Conversation
test_committed_catalog_is_current_and_valid pinned the exact list of stripped period spellings in the committed catalog. Every resolver append that recorded the next weekly claims print added a spelling (week_2026-08-29, week_2026-09-05, ...) and failed the required "Arch checks" status, so proposals merged past it with the resolver's admin token (#240 on 2026-09-03, 598f394 on 2026-09-29) and the check stopped meaning anything. The list stood for one question: has a curator decided that this strip is a period label and not a statute, cohort, or edition label that happens to spell its row's period? The test now asks that per (spelling, concept) pair: - build_series_catalog.stripped_segment_review_problems audits the catalog's stripped_segments against a reviewed map (tests/fixtures/series_catalog/reviewed_stripped_segments.json, the catalog at 55bbf3d that #244 reviewed, with each strip's kinds). - A strip outside the map passes only if its concept already has a reviewed strip of the same period_spelling_template (the same way of writing a period) and every observation behind it spells its own declared period directly (kind derived). - New concepts, new templates, unreviewed overlap strips, reviewed strips that gain the overlap kind, reviewed strips that disappear, non-period spellings, and catalog/plan disagreements all still fail. A concept that starts stripping an already-listed spelling used to pass unseen; it now fails. build_catalog exposes each strip's classify_segments kinds as plan["stripped_kinds"]; catalog bytes are unchanged (--check green). week_2026-06-13 and week_2026_06_13 are not a naming bug: both come from the one 2026-06-13 initial-claims row (ledger line 44), whose source_record_id uses ISO hyphens and whose measure.concept uses underscores. Both strip as overlap because that row declares a month (the cadence defect in docs/catalog-curation-backlog.md). Documented in the fixture notes and the backlog, and asserted by the fixture test. Hypothesis joins the dev extras with the same pyproject and uv.lock change as #306. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Adopting this PR to land it. Its authoring session can't be found in the session index, and the PR has had no activity since 2026-09-30. Why it matters now: the ledger branch's required "Arch checks" job has been red since 598f394 (the stale stripped-spelling list in Plan: bring the branch up to date with Session: Resolve duplicate Chronicle lineages for three BLS concepts (local_c7ccacf7-d314-449b-b837-d0cd5835d3e0). |
…rinted Two resolver appends landed after this branch was written. - 2ed9bae recorded abs.cpi.all_groups.yoy for 2026-08 as abs.cpi.all_groups.yoy.2026_08.first_print. The segment is the row's own period with an underscore; the concept's June print used a hyphen, so the audit reported the concept's first 9999_99 strip. Reviewed and recorded. - d7e45bc printed week_2026-09-19 for us.dol.initial_claims.sa, the week the corruption self-test used as unprinted, so two of its cases stopped corrupting anything. The test now derives a week one year past the latest printed week and asserts it is absent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Update from the adopting session. I am not landing this PR. The independent GPT-6.1 Sol review at 0852fcd requested changes (full report:
#344 (Max's ruling d353) no longer depends on this PR. It re-pins the existing list as routine maintenance, the way #244 did, and carries the same Hypothesis dev-dependency hunks as this PR, so the two merge cleanly in either order. A follow-up session to address the findings above is proposed to Max. |
The independent review of 0852fcd executed a copy of the 2026-08 ABS CPI first print moved to 2026-09 with the period also spelled inside measure.concept (abs.cpi.2026_09.all_groups.yoy). The builder folds it into the reviewed abs.cpi.all_groups.yoy identity under a new family pattern, abs.cpi.{P}.all_groups.yoy, and the template-only audit passed it: the measure.concept slot borrowed the approval of the source_record_id period suffix. A reviewed decision now covers one concept, one identifier field (measure.concept or source_record_id) and one strip_shape: the field's family pattern with each {P} written {P:<period_spelling_template>}, so it fixes every kept segment, where each stripped segment sits and how it is spelled. Only a calendar substitution inside a reviewed shape passes without curation; a new field, position, template or kept segment is reported. The build plan's stripped_kinds becomes strips (concept -> field -> shape -> spelling -> kinds); catalog bytes are unchanged. Literal {P:...} segments join {P} as reserved, so a shape never mistakes a kept segment for a stripped one. The reviewed fixture is regenerated in that form from 55bbf3d's inputs (the catalog #244 reviewed) plus the 2026_08 ABS CPI decision; it covers exactly the same 176 (spelling, concept) pairs with the same kinds. The corruption self-test now derives its unprinted week from initial claims and asserts only that the initial-claims pair is absent, and runs once with a continued-claims print of that same week, so another concept's valid continuation can no longer break it. New tests: the review's exact regression on the real ledger; field, position and kept-segment examples; a new_shape novelty in the A2 property; T4 (shape = identifier up to calendar values); A6, a reference model of the rule compared with the audit in both directions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…period-invariant Conflicts: build_catalog keeps both plan keys (entity_folds_applied from #344, strips from this branch); test_committed_catalog_is_current_and_valid keeps the reviewed-strip audit in place of #344's one-time re-pin of the exact spelling list. The committed catalog now declares entity_folds_sha256, so _committed_build, the ABS CPI regression and the next-period test pass bsc.ENTITY_FOLDS, and the independent replay resolves a row an active fold absorbs (fold geography and absorbed entity, concept among the declared absorbed_names, read from the seed) at the survivor entity. The folds change no strip: the reviewed fixture is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the independent review of 5fa0c34 (APPROVE, one MINOR, three NITs): - MINOR: the real-ledger next-period test skipped the 66 observations whose period is a month name, because the successor has both a full and an abbreviated spelling of the same template. _respell now keeps each month word full or abbreviated as written ("may" is both, so its successor is written in full), and the test asserts it appends every eligible observation (223 of 223), not ">= 100". - The curation backlog no longer says a re-perioded June-13 row makes its strips disappear: re-spelling or retracting the row does; re-perioding it to its week keeps the strips and reports gained kinds. - period_spelling_template, strip_shape, the module docstring, the audit docstring, the backlog and the fixture comment now say shapes agree up to the digits and month words the template normalizes (qualifier digits and full/abbreviated month names included), not "only calendar values". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged at head
|
Problem
test_committed_catalog_is_current_and_validpinned the exact list of stripped period spellings in the committed catalog. Every Thesis resolver append that records the next weekly claims print adds a spelling (week_2026-08-29,week_2026-09-05, …), so every append failed the required "Arch checks" status. The resolver merges through the API with an admin token (it waits only for "Append gate"), so the red check was ignored:What the list protected
The builder can't tell a real period label from a statute, cohort, or edition label that happens to spell the row's own period.
stripped_segmentsexists so a curator can catch that (build_series_catalog.pymodule docstring;classify_segments). The exact list forced a human look at every new spelling. It also failed when a spelling disappeared.It had a gap: only spellings were pinned, not concepts. A new concept starting to strip an already-listed spelling (for example
2026_07) passed unseen.The invariant now checked
build_series_catalog.stripped_segment_review_problems(stripped_segments, strips, reviewed)audits every strip. A strip is keyed by (canonical concept, identifier field, strip shape, spelling):measure.conceptorsource_record_id;strip_shape) is that field's family pattern with each{P}written{P:<template>}, for exampleabs.cpi.all_groups.yoy.{P:9999_99}.first_print.period_spelling_templateturns digits into9and month words into<month>, and keeps separators and literal words. So a shape fixes every kept segment and where each stripped segment sits. Two identifiers share a shape exactly when they have the same kept segments, stripped slots in the same positions, and the same template in each slot. They can differ only in what the template normalizes: digits, including those inside anafter_<qualifier>_slot, and month words, with full and abbreviated names counting as one spelling.The reviewed map is
tests/fixtures/series_catalog/reviewed_stripped_segments.json, keyed concept → field → shape → spelling →classify_segmentskinds. It holds the catalog at 55bbf3d that #244 reviewed, plus the 2026_08 ABS CPI decision (see notes).A strip that is not in the reviewed map passes only when both of these hold:
derived, neveroverlap).Everything else is still reported:
week_ending_…where it usedweek_…)abs.cpi.2026_09.all_groups.yoy,….revised)build_catalogexposes the strips asplan["strips"]. The catalog bytes do not change:--checkis green, the byte-regeneration assertion passes, and no catalog keys are added, so Thesis's frozenCATALOG_TOP_LEVEL_KEYS/CATALOG_ROW_KEYSare unaffected. Literal{P:...}segments are now reserved alongside{P}(no current ledger or docket-seed identifier uses one), so a shape can never mistake a kept segment for a stripped one.Why field and shape, not just concept and template (review of 0852fcd)
The first version of this PR keyed decisions on (concept, spelling template). The independent review executed a copy of the 2026-08 ABS CPI first print (ledger line 231), moved to 2026-09, with its period also spelled inside
measure.concept:The builder folds it into the reviewed
abs.cpi.all_groups.yoyidentity with no mint, under a new family patternabs.cpi.{P}.all_groups.yoy. The template-only audit passed it, so an unreviewed cohort or edition slot inside the concept borrowed the approval of thesource_record_idperiod suffix. Now thesource_record_idstrip passes (reviewed shape), and themeasure.conceptstrip is reported:test_a_reviewed_template_in_a_new_concept_position_needs_reviewis that exact regression on the real ledger.week_2026-06-13vsweek_2026_06_13Not a naming bug. Both come from the one 2026-06-13 initial-claims row (ledger line 44):
source_record_idisus.dol.initial_claims.sa.week_2026-06-13(ISO hyphens);measure.conceptisus.dol.initial_claims.sa.week_2026_06_13(underscores).The builder strips period tokens from both fields and records each distinct spelling. Both strip as
overlapbecause the row declaresmonth 2026-06, the cadence defect already indocs/catalog-curation-backlog.md("Initial claims cadence metadata"). They are now two reviewed strips, one in each field's shape. The fixture notes and the backlog document this, andtest_reviewed_stripped_segments_fixture_is_wellformedasserts it.Evidence on real data
The fixture was regenerated from 55bbf3d's inputs with this builder. It covers exactly the 176 (spelling, concept) pairs the previous fixture listed, with the same kinds, now as 354 strips in 297 (concept, field, shape) decisions across 120 concepts.
Each merged append since 55bbf3d and each refused proposal head, built with this branch's builder (before the #344 merge, which changes no strip) and audited against the #244 map (the fixture without the 2026-10-12 ABS CPI decision):
78308f8(refused)7917dbe(refused)7bc1595(refused)177c461(refused)'2026_08' on 'abs.labour.unemployment_rate': first strip in source_record_id shape 'abs.labour.unemployment_rate.{P:9999_99}.first_print'…'2026_08' on 'abs.cpi.all_groups.yoy': first strip in source_record_id shape 'abs.cpi.all_groups.yoy.{P:9999_99}.first_print'…Scoping by field and shape added no false alarms on any routine append. The two remaining reports are real curation events:
abs.labour.unemployment_ratetook its first print beside an already-observedabs.labour.unemployment_rate.australia, which looks like a concept-spelling duplicate.2026-06to2026_08in itssource_record_id. 0852fcd reviewed that strip (a period label) and recorded it with a note. Against the full fixture, 2ed9bae and d7e45bc have no problems.Invariants (tested)
Property tests use Hypothesis, derandomized so this required check stays deterministic:
mayis both.measure.concept, which folds into the reviewed identity, or beside a new kept segment ofsource_record_id;Other tests:
test_strips_match_an_independent_replayre-derives every strip from the ledger withclassify_segmentsandperiod_spelling_templatealone: its field, its shape, and its kinds. It resolves each observation to its catalog row through that row's concept and aliases, and requiresplan["strips"]and the catalog'sstripped_segmentsto agree exactly.source_record_idstrips a period and all its strips are direct spellings), append the next period written the same way, month words kept full or abbreviated as written. The test asserts all 223 are appended (the first version skipped the 66 month-name prints). They land on the existing identities with no mints, supersedes or drops. They add ≥50 new strips, all in shapes their concepts already strip in, and none needs review.test_strip_audit_flags_a_reviewed_template_in_a_new_shapecovers four cases, each folding into the reviewed identity:measure.concept;source_record_idstrips, but inmeasure.concept;.revised);source_record_idposition.test_committed_audit_fails_on_corrupted_catalogsderives its unprinted week from initial-claims prints and asserts only that the initial-claims pair is absent (the review's minor finding). It runs once with a valid continued-claims print of that same week, the case that broke the old global-absence assertion.source_record_idonly;{P}only;Scope and coordination
Fold seven entity-drift lineages into their economy/aggregate siblings #344 (entity folds) merged first (65822f4); this branch merges it in f2a6d76. The Hypothesis
pyproject.toml/uv.lockhunks were identical.build_catalogkeeps both plan keys (entity_folds_applied,strips). The committed test keeps this audit in place of Fold seven entity-drift lineages into their economy/aggregate siblings #344's one-time re-pin of the exact list._committed_build(), the ABS CPI regression and the next-period test passbsc.ENTITY_FOLDS. The replay resolves a row that an active fold absorbs at the fold's survivor entity: geography and absorbed entity match, and the row's concept is one of the declaredabsorbed_names, read straight from the seed. The folds change no strip, so the reviewed fixture is unchanged.Unchanged pins: the row-count pin (
== 221since Fold seven entity-drift lineages into their economy/aggregate siblings #344) andtest_identity_uuid_map_matches_reviewed_anchorfire on identity events (mints, enrichments, supersedes).suspect_segments == ["LNU02374597"]fires on those and also on any new date-like kept segment (for example asource_record_idending.edition_2026), with no identity event. The repo documents all of these as needing curation.CI steps run locally (receipt 0.6.2, Python 3.14, Hypothesis 6.169, ruff 0.14.10):
build_series_catalog.py --check;pytest tests/test_build_series_catalog.py(222 passed at ab6d9b9);--verify-registry-append-onlyagainst the base registry;ruff checkon both changed Python files.I did not run the Arch-surface pytest list, the DB build or the wheel steps locally. No module outside this test imports the builder or reads the plan, and CI runs them.
ledger/is untouched.axiom: n/a: catalog test and tooling change, no policy logic.
🤖 Generated with Claude Code