Skip to content

Cite NZ spec sources by symbol or stable record, never by a drifting line - #1282

Merged
MaxGhenis merged 6 commits into
mainfrom
nzhub/nz-spec-line-citations
Oct 15, 2026
Merged

MaxGhenis merged 6 commits into
mainfrom
nzhub/nz-spec-line-citations

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes #1141 and #1142. Their owner session is gone and both conflicted with main. This PR rebuilds #1141's guard fresh on main (121fd4d) and extends it to every NZ line citation main gained since then.

Invariant

No resource in the NZ spec package (packages/microcosm-build/src/microcosm/build/nz/, JSON and spec/*.yaml) cites a line number of a file in this repository. Another repository's file may be cited by line only when the same resource pins that file at a commit. The pin is a mapping whose path names the file and whose commit is 7–40 lowercase hex.

#1141 limited this to .py files. This PR covers every extension, so it includes JSON line ranges such as axiom_input_closure.json:1045-1052.

Changes

Resource Was Now
benefit_unit_rule.json pointer block concepts.py:889-928 concepts.py, the # --- Relationships block, _pointer("partner_person_id") through _pointer("reference_person_id")
benefit_unit_rule.json description executor.py:638-645, :1549-1554, population_kernels.py:208-232 microcosm.graph.executor._structural_columns, ._validate_population_declaration, microcosm.build.transport.population_kernels.TransportCreateKernel
benefit_unit_rule.json parent-1 rule, hours evidence concepts.py:900-907, :1069-1083, policyengine_us_concepts.py:352-362, transport.py:843-849, policyengine-us.md:31 symbols and a doc heading anchor
reporting_classifiers.json implementation population_kernels.py:209-228, transport.py:843-856 TransportCreateKernel, read_populace_us_donor
reporting_classifiers.json evidence ×3 axiom_input_closure.json:1045-1052, :1183-1204, nz.json:670-688, concepts.py:990-1000,1040-1051 keyed record selectors (axiom_input_closure.json#/entries[input=…], nz.json#/bindings[canonical_input=…]) and symbols
scenarios.json MC12 note ops main run.py:168 WEEKS_IN_MODEL_YEAR in ops nz-lane/emtr_reproduction/run.py at ba6e7d6e. The hub read it there: line 168 is WEEKS_IN_MODEL_YEAR = D365 / D7, with D365 = Decimal(365) and D7 = Decimal(7)

Tests (engine-free, test_nz_spec_package.py)

  • The guard. It covers every extension and every locator spelling, in values and in mapping keys, at any depth. Existing foreign pins are found and covered by their pins, which shows the exemption isn't vacuous: as_rate_bridge.json's run.py lines and the engine_source_pins .rs files.
  • Resolvers. Every dotted microcosm.* symbol imports. Every file.json#/pointer resolves at HEAD.
  • Keyed record selectors (#/array[field=value,…], RFC 6901 escaping, optional pointer suffix) must match exactly one record. An index step into an array of mappings is refused in both scanning and resolution, because positions drift the way line numbers do. A Hypothesis property inserts the target at any position among distinct-keyed records and checks that the selector still finds it while the index form is refused. Inserting a dummy record at index 0 of the closure and of nz.json leaves all three citations resolving to the same records. Keys:
    • Closure: input, which is unique in the current NZ closure (140 of 140). The code's identity is the composite InputRef(input, entity, module) (input_closure.py:345, duplicates refused at :480), and the resolver refuses any future ambiguity.
    • Binding: canonical_input (89 distinct; engine_input repeats).
  • Regression vectors. Each replaced citation, and each of Cite NZ spec sources by symbol, not line number #1141's five, is refused.
  • Hypothesis properties. These are ported from Cite NZ spec sources by symbol, not line number #1141.
  • Differentials. Each pointed record is the one the resource describes, for example /entries/99's input is nz_super_shares_residence_with_person_at_least_adult_age. Each cited symbol still does what the resource says.
  • Mutants. Each of these failed its intended test and was restored: re-adding concepts.py:889-928, renaming a cited symbol, a pointer to a missing key, and a foreign pin changed to main.

Results at 9813c9e, each from a single-file run with JUnit counts: test_nz_spec_package.py 279 passed, test_country_spec.py 135 passed, test_nz_axiom_input_closure.py 17 passed, 1 skipped (optional real-engine probe). At 11fc476, the four transport-kernel files (24 / 30 / 30 / 31) and test_spec_engine_country_bundles.py (21) also passed; this fix round didn't touch them. Before the fix, the new selector tests failed 20 of 20 against the index-based code. That count is from the fix lane's run, so it is author-reported and has no CI receipt.

Re-pins

tests/golden/nz_country_spec.json:

  • benefit_unit_rule.json 5c1cf16d… → a9e8cbfd…
  • reporting_classifiers.json b5af9e47… → d1a5011e…
  • scenarios.json 30f96f30… → 9c70241a…
  • country fingerprint 3208901a… → 9259333d…

The NZ package_fingerprint (07ab080d… → e2f1d71e… at 9813c9e; bba0d1ac… was the intermediate value at 11fc476) is derived (spec_engine/loader.py:434), and no file pins it. A search of full hashes and 8-character prefixes found no other pins. spec_sha256 and documentation_sha256 are unchanged.

Status

  • Done: the keyed-selector fix round (9813c9e). It replaced #/entries/99, #/entries/115 and nz.json#/bindings/40.
  • Cite NZ spec sources by symbol, not line number #1141 and Cite code by symbol, not line number, in the NZ benefit-unit rule #1142 are closed and point here.
  • Review r1 (GPT-6.1 Sol, at 9813c9e) asked for changes.
    • Its blocking finding: the guard missed Markdown-style and L-prefixed spellings such as `concepts.py` lines 889-928 and concepts.py (L889-L928). Fix round 2 (b1be0d9) fixed it: the wrapper, L-prefix, reverse-order, dash and ll. spellings are all refused. test_nz_spec_package.py reports 619 passed. The old recognizer failed 172 of the 192 new regression cases, and the three recognizer mutants each went red.
    • Its body notes (the package fingerprint and the closure identity) are corrected above.
  • Delta review r2 (b1be0d9) asked for changes.
    • A Markdown link's destination was not attributed. [upstream.rs](concepts.py) lines 889-928 borrowed a pinned foreign file's exemption, which is a soundness bug.
    • A keyed selector whose value looked like file.py:L12 was flagged, a false positive.
  • Fix round 3 (deaf49f) changed three things.
    • The link destination is now the cited file, and a pin exempts a citation only when every attributed file is a pinned foreign file.
    • Pointer and selector fragments are opaque to the line scan.
    • The guard's threat model is in the module docstring: it catches plausible authoring spellings, not deliberate obfuscation.
    • test_nz_spec_package.py reports 662 passed.
  • Delta review r3 (deaf49f) asked for changes. GitHub URL destinations such as [source](https://github.com/PolicyEngine/microcosm/blob/main/…/concepts.py#L889-L928) were dropped from attribution.
  • Fix round 4 (b10b14d) fixed it.
    • URL destinations (GitHub blob, raw, raw.githubusercontent, and bare URLs) are parsed, and #L fragments are read as line locators.
    • This repository's URLs are local files and are never exempt.
    • Other repositories' URLs need a same-resource {path, commit} pin whose path equals the URL's file path. A pin naming only the file name does not cover a URL; this is deliberate.
    • A link the guard can't parse is scanned, not masked.
    • test_nz_spec_package.py reports 947 passed.
  • Delta review r4 (b10b14d) asked for changes on two points. A foreign URL could borrow a pin for a different directory's file of the same name. Trailing : ! ? … — after a bare URL hid its #L fragment.
  • Fix round 5 (7b6d122) fixed both.
    • A URL file is covered only by a pin whose path is exactly that file's path. File-name matching remains for plain prose only.
    • #L fragments are parsed by grammar, so trailing punctuation can't hide them.
    • A URL whose fragment couldn't be parsed is scanned, not masked.
    • The lane ran 421 probes against the live helpers before returning: wrappers, punctuation, reference-style and HTML links, ?plain=1, #L5-10, blame and permalink URLs, and pin-path normalization. The parent commit got 206 of them wrong; this commit gets all 421 right.
    • test_nz_spec_package.py reports 1,189 passed.
  • Delta review r5 is running. Then land on green.

Out of scope: #1146, the US/UK guard, is orphaned too and also carries #1141's NZ part. It is tracked separately and should drop its NZ files on rebase.

🤖 Generated with Claude Code

Invariant: No resource in the NZ spec package
(packages/microcosm-build/src/microcosm/build/nz/, JSON and spec/*.yaml)
cites a line number of a file in this repository. Another repository's
file may be cited by line only when the same resource pins that file at
a commit, in a mapping whose path names the file and whose commit is
7–40 lowercase hex.

Rebuild #1141 on current main without merging its branch. Replace all
local Python/JSON/Markdown line locators with symbols, exact JSON
records, or a documentation heading. Preserve resource meanings and
field shapes. Guard all extensions, nested values/keys, foreign pins,
symbol resolution and JSON pointers; add properties and differentials.

Regenerate only changed NZ golden resource hashes and fingerprint:
benefit_unit_rule.json: 5c1cf16daaae482ea3ec53495f4c2e4ae452d928c6240a5284dbbf30cd2dfe37 -> a9e8cbfd38a64d2f8db0002fe8c31bb5a18fb34dbe59fa943336487ce95e2ca8
reporting_classifiers.json: b5af9e4737af4717d86aedfe651df8b3c18c3875763726e7a6a0b9b1168ed133 -> 789a07acd1b6724a12bbd9584ab9fa05bb01d0b675cc3a0fbc837b066dbec49e
scenarios.json: 30f96f3063773d77e3c70119c8f5d99d3528eca87428903da00ca071ab34cfaf -> 9c70241a6203b3a66dc09587c8b955d9d421bbe32f018ea1542e7639f4c7507c
country_fingerprint: 3208901a27e6f09885e5990517c80e2d418425d937aa33fb0f6dacbbf290dd23 -> 5e97ffb44bc37ebd3809e7f6cf2ad253ef4308339338b96b4bd78746a9c1888d
package_fingerprint: 07ab080d68771a207290c83a9040b294f0775c96b74022938c9da13aa713ba20 -> bba0d1ac41b972314bfa5f95adb9884c462296713af50f68d3969246a0c6f112
No other repository pins moved; searched full hashes and 8-char prefixes.
package_fingerprint is derived; no file pins it.
spec_sha256 and documentation_sha256 are unchanged.

Validation: 542 passed, 1 skipped across eight final targeted
test-file runs; all four required mutants fail their intended tests and
are restored. Ruff check/format and git diff --check pass.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Extend NZ JSON citations with exactly-one keyed record selectors, conjunctions,
RFC 6901 escaping and pointer suffixes. Refuse record-array index traversal in
both citation scanning and resolution; retain scalar-array indexing.

Use unique input identities in the closure and canonical_input in Axiom
bindings (engine_input is not unique). Change only the three evidence strings.

Regenerate the NZ golden; only reporting_classifiers.json and fingerprint move:
reporting_classifiers.json: 789a07acd1b6724a12bbd9584ab9fa05bb01d0b675cc3a0fbc837b066dbec49e -> d1a5011e2163a4ceec5f030e155a02f7bc4a3bc0ad59f06fb7a406993319512f
country_fingerprint: 5e97ffb44bc37ebd3809e7f6cf2ad253ef4308339338b96b4bd78746a9c1888d -> 9259333d5b7c212209654cebabc06122a8bc2dbe2cb1c776af17c6d02f1200fe
Full hashes and 8-character prefixes checked; no stale tracked pins remain.

Tests: test_nz_spec_package.py 279 passed; test_country_spec.py 135 passed;
test_nz_axiom_input_closure.py 17 passed, 1 skipped. Total: 431 passed,
1 skipped. Initial regressions: 20 failed on the original resolver/resources.
All four required mutants fail their intended tests and are restored byte for
byte (1 index, 1 wrong-record, 3 scratch duplicate, 1 exactly-one failures).
Ruff check/format, CI test-layout and graph-burndown verification, and
git diff --check pass.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review October 15, 2026 04:28
MaxGhenis and others added 4 commits October 15, 2026 02:21
Share the file-line locator grammar between regular and extensionless files.
Recognize Markdown and quote wrappers, forward/reverse L locators,
punctuation, and range/list spellings. Document recognized forms and scope.

Add deep mapping-key/value regressions and extend Hypothesis generation
across wrappers and dash variants. Preserve symbol, JSON-pointer and keyed
record citations, with explicit negative controls.

Validation: NZ spec 619 passed; country spec 135 passed; NZ closure 17 passed,
1 skipped. Physical control and three restored mutants fail as intended.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Attribute link locators to the destination and every filename in the label.
Exempt a citation only when all attributed files are pinned foreign sources.
Keep JSON pointer and keyed-selector fragments opaque to the line scanner.

Document the prose-citation threat model and exercise its in-scope examples,
deep key/value regressions, and generated link attribution and exemptions.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Parse HTTP(S) file URLs in Markdown destinations and bare prose, including
GitHub blob/raw forms, raw.githubusercontent.com, and line/column fragments.
Retain repository identity so microcosm URLs are always local and foreign
URLs require the existing same-resource path and commit pin.

Leave unparseable links available for full-text scanning. Extend deep key
and value regressions and the link attribution property across URL forms.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Keep basename pin matching for prose while requiring exact paths for URL
citations. Parse line fragments by their positive grammar and preserve raw
fallback scanning when a fragment is not understood.

Cover punctuation, common URL wrappers, encoded paths, lowercase and short
ranges, commit permalinks, and tree/blame routes with regressions and properties.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@MaxGhenis
MaxGhenis merged commit c28b453 into main Oct 15, 2026
10 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

Merged by the NZ hub (session local_e407a527) at 7b6d122 with --squash. Gates: gh pr checks exit 0; MERGEABLE; not draft; no CHANGES_REQUESTED review. Reviewed head: 7b6d122. Independent review: GPT-6.1 Sol, five rounds (jobs 20261015-002850, -022135, -025925, -035716, -045301). r1–r4 asked for changes; fix rounds 1–5 addressed each finding. r5 APPROVE_WITH_NITS at 7b6d122, Needs Max: no. Its two P3 nits are not blocking: an encoded punctuation-ending filename, which is contrived and used by no NZ citation, and a stale summary file outside the repo, now removed. Supersedes #1141 and #1142.

@MaxGhenis
MaxGhenis deleted the nzhub/nz-spec-line-citations branch October 15, 2026 09:56
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