Skip to content

Cite code by symbol, not line number, in the NZ benefit-unit rule - #1142

Open
MaxGhenis wants to merge 2 commits into
mainfrom
nz-benefit-unit-rule-durable-citation
Open

MaxGhenis wants to merge 2 commits into
mainfrom
nz-benefit-unit-rule-durable-citation

Conversation

@MaxGhenis

Copy link
Copy Markdown
Contributor

What

packages/microcosm-build/src/microcosm/build/nz/benefit_unit_rule.json cited code by line number. After #888 (merge 2743422) the two executor citations were stale:

Cited as Actual on origin/main 2743422
_structural_columns, executor.py lines 636-643 packages/microcosm-graph/src/microcosm/graph/executor.py lines 638-645
_validate_population_declaration, executor.py lines 1550-1573 same file, lines 1531-1554

The same file carried two more line citations into microcosm-frame's concepts.py, and both had drifted too:

Cited as Actual
pointer_concepts.citation: concepts.py:880-919 the relationship pointers are lines 881-922 (the cited range cut off the reference_person_id pointer)
composition[dependent_child].rule: "the pointer definition, concepts.py lines 892-901" parent_1_person_id is lines 893-902

All four now cite the symbol and drop the line number:

  • microcosm.graph.executor._structural_columns
  • microcosm.graph.executor._validate_population_declaration
  • microcosm.frame.concepts, specifically the partner_person_id, parent_1_person_id, parent_2_person_id and reference_person_id pointer concepts
  • the parent_1_person_id pointer definition in microcosm.frame.concepts, and microcosm.frame.concepts._check_pointers

Nothing in the repo asks for line-number citations (docs/agent-guide.md has no citation rule), and no code reads these strings: pointer_concepts.citation has no reader. Symbol names survive edits above them, and a grep finds them.

I re-read each prose claim against the current code, and each still holds:

  • _structural_columns returns each entity's id column, plus the membership columns for the person entity.
  • _validate_population_declaration raises NodeRejected when a StructuralDelta.NONE node owns one of those columns.
  • _check_pointers reports parent_2_person_id without parent_1_person_id as parent_order.
  • The parent_1_person_id description says that a lone co-resident parent is always parent 1.

Only string values changed. Keys, structure and every rule value are untouched.

Pins moved

benefit_unit_rule.json is a declared NZ country-spec resource (nz/country_package.json, kind: legacy_json). load_country_spec hashes the bytes of every resource, and ResolvedCountrySpec.fingerprint is the composition fingerprint over those hashes. So this edit moves:

  • the benefit_unit_rule.json sha256 in tests/golden/nz_country_spec.json: 9e507e78…a653 → a5f37485…f148
  • the NZ composition fingerprint in the same golden: df8850d5…fd48 → a3229c53…c371

The golden was regenerated with the test's own _loaded_spec_summary("nz") and canonical_json_bytes. Its diff is exactly those two lines, and the am and be goldens are unchanged.

Hash sinks checked that do not move a pin

I traced the file's bytes to every hash in the repo from three angles (code trace, literal grep, open PRs), then had a critic re-verify the result. Nothing else is pinned. Each sink below was read in the code:

  • Spec engine. legacy_json resources get empty projections on every surface (spec_engine/loader.py), and compiler_ir._normalized_resources skips them. So the NZ spec_sha256, documentation_sha256, compiled IR, spec_binding and plan lock do not move. The spec engine's per-file FileReceipt and package_fingerprint do move, but no NZ bundle.lock.json or plan.lock.json is committed. test_spec_engine_reemission[nz] compares emitted values with reloaded ones rather than with literals.
  • US-only artifacts. inventory_coverage.EXPECTED_HASHES, the field_usage counts, tools/spec_engine_coverage.py and docs/evidence/spec-engine/us-f0-coverage.json are all US-only, and none of them reads legacy_json.
  • Country-spec consumers. Every graph-node binding of a country-spec fingerprint or resource_hashes is in uk_runtime and calls load_country_spec("uk"). No NZ graph or runtime exists yet. transport/binding_identity.py hashes .py sources only, and orrery.py (Export Microcosm schema metadata for Orrery #888) exports compiled graphs.
  • code_identity.builder_code_identity. It moves, as it does on any source edit, but nothing pins a live value.
  • Other repos. Neither chronicle nor policyengine.py on main pins the old sha or the old fingerprint.

Landing order (NZ hub)

Two open NZ hub PRs also edit tests/golden/nz_country_spec.json:

The NZ hub holds build/nz edits until #1122 lands, so this PR lands after #1122 and #1138. At land time, merge main and regenerate the golden from the loaded spec; this PR still changes only the benefit_unit_rule.json hash and the fingerprint:

PYTHONPATH=. .venv/bin/python -c "import importlib.util as u; s=u.spec_from_file_location('t','packages/microcosm-build/tests/engine_free/shared/test_country_spec.py'); m=u.module_from_spec(s); s.loader.exec_module(m); (m.GOLDEN_ROOT/'nz_country_spec.json').write_bytes(m.canonical_json_bytes(m._loaded_spec_summary('nz')))"

After that, git diff against the merged main should show only those two golden lines.

Tests

Targeted run with -p no:cacheprovider --basetemp=.hub-scratch/pytest -o tmp_path_retention_policy=failed, all under packages/microcosm-build/tests/engine_free/shared/:

  • test_country_spec.py
  • test_nz_spec_package.py
  • test_spec_engine_country_bundles.py
  • test_spec_only_country_packages.py
  • test_spec_engine_reemission.py

Before the re-pin, the first three files gave 1 failed and 225 passed. The one failure was TestGoldenCountrySpecs::test_loaded_spec_matches_the_golden_file_byte_for_byte[nz]. After the re-pin, all five files gave 242 passed. CI runs the whole suites. tools/ci_test_plan.py puts both changed paths in the shared scope, so every job runs.

Invariants

  • Only string values changed. Parsed as JSON, the old and new files have identical key sets at every depth, and every non-prose value is equal.
  • Determinism: the golden equals canonical_json_bytes(_loaded_spec_summary("nz")), and the same bytes come back on reload (test_fingerprint_is_stable_across_loads).

No logic changed, so there is no new property-based test.

axiom: n/a: documentation string in a microcosm build resource, no policy change

🤖 Generated with Claude Code

MaxGhenis and others added 2 commits October 7, 2026 15:36
benefit_unit_rule.json cited microcosm.graph.executor by line range
("executor.py lines 636-643", "lines 1550-1573"); after #888 the two
functions sit at lines 638 and 1531, so both ranges were stale. The two
concepts.py citations in the same file ("concepts.py:880-919", "lines
892-901") had drifted too. All four now name the symbol: the executor's
_structural_columns and _validate_population_declaration, the
microcosm.frame.concepts pointer concepts, and _check_pointers. The claims
themselves were re-read against the current code and still hold.

The file is a hashed NZ country-spec resource, so the edit moves its
sha256 and the NZ composition fingerprint; tests/golden/nz_country_spec.json
is regenerated from the loaded spec (those two values only).

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

This branch has not been deployed

No deployments
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