Skip to content

Build the UK national line through the rowwise driver's release role (#823) - #965

Merged
juaristi22 merged 11 commits into
mainfrom
uk-823-national-line-through-rowwise-driver
Sep 22, 2026
Merged

juaristi22 merged 11 commits into
mainfrom
uk-823-national-line-through-rowwise-driver

Conversation

@juaristi22

@juaristi22 juaristi22 commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #823 (build-path consolidation). One driver now builds both UK dataset lines: tools/build_uk_rowwise_candidate.py --release-role {national,dense}. The national role builds the certified national line without cloning, on national targets only, under the calibration-seam doctrine, by delegating to the seam library; the retiring tools/calibrate_uk_national_dataset.py is removed after a parity twin. The dense role is today's K=15 joint build, fenced by its role. The publication side of #823 (line pointers, registry default, promotion) is on separate branches for Max's review; this PR does not touch latest.json, the registry or the loader.

What changes

Release role and posture (B1). --release-role is required. A frozen posture record (uk_runtime/rowwise_posture.py) declares each role's doctrine object, clone count, solve length, learning rate, seed, target-weighting rule and its admissible overrides, gate scope and posture, Logbook pipeline and attempt-id prefix, staging operation id, release id and output filenames. The driver fills the role's defaults into unset solve flags, records which flags were given explicitly, and refuses the other role's flags by name before any value is range-checked (national refuses --ladder, --n-clones, the size flags, --sample-fraction, grain_equal, --release-candidate with the seam's own reason, and a --seed that is not the doctrine's; dense refuses --target-loss-cap, --allow-unpinned-feed, family_equal). The manifest and the dry-run plans record release_role; the manifest records release_id and bumps schema_version to 4 (documentary: no rowwise-manifest reader compares the version; the pre-flight and the assembler gate on release_role, and that gate runs before --allow-missing-staging, so a pre-lane run is refused on the role, not on missing staging); the size-checkpoint identity carries the role so a pre-role checkpoint refuses to resume.

Doctrine. UK_NATIONAL_SOLVE_EPOCHS = 1500 and UK_NATIONAL_TARGET_WEIGHT_RULE = "family_equal" (María's ruling of 2026-09-20, given in session while planning #823; her acknowledgement on this PR is the openable record the doctrine comment points at): the certified-cut posture every campaign national run had overridden to is the doctrine, so a doctrine run records no overrides; uniform stays a receipted per-run override. The pinned tests move with the constants.

Dense line. The pre-flight and the assembler accept only a manifest whose release_role is dense (a pre-role candidate is rebuilt, never grandfathered). The published artifact is microcosm_uk_2024_25_dense.h5, mirrored in the contract as _UK_DENSE_DATASET_FILENAME and in the data registry's dense variant, under a three-legged lockstep pin (assembler, contract, registry). The driver's joint-surface outputs are microcosm_uk_2024_25_local.h5 and microcosm_uk_2024_25_local.local_gates.json (the _local family stays because the size evaluator and the pre-flight glob it).

National role (B2). _run_national_role pins the input, opens telemetry under a seam-minted attempt id, compiles the national register from the pinned Ledger artifact with the committed feed-pin check (now uk_runtime.chronicle_feed.require_committed_uk_chronicle_feed_pin), freezes it as national_target_registry.json (the scorer's register), and calls run_uk_calibration with the seam's direct_h5 resolver. The seam writes microcosm_uk_2024_25.h5, calibration_diagnostics.json, the signed microcosm_uk_2024_25.terminal_gates.json, build_record.json and the uk/frs Logbook row exactly as before, so tools/certify_uk_release_cut.py and the national assembler are untouched. The driver adds the rowwise manifest (uk_national_calibrated_candidate), the two reviewed telemetry artifacts and the staged bundle under staged/<attempt id>/, then re-binds the manifest to the post-finalizer build record. --dry-run compiles the register and prints the plan.

Staging. The driver's default upload cadence is 300 s (the Hub allows about 128 commits per hour per repository; the v20 run lost uploads at 30 s); add_staging_arguments takes a per-command default. A refused stage event is reported and dropped instead of aborting the build (the #946 follow-up). The last-mile gap the v20 run met is closed in staging_v2: three consecutive rate-limit failures used to pause remote writes for the rest of the run, so complete()'s forced upload was skipped and the remote progress.json stayed running; completion and failure now re-open the best-effort session for a bounded terminal flush (0/15/60 s) and warn once if all three miss.

Retirement (B3). The seam command and its test module are removed; its behaviours re-anchor on the driver (test_uk_rowwise_national_role.py, the chronicle feed tests). Runbook 623, runbook 806 §1–§3, the staging operations guide and the README name the one driver.

Verification

  • Review round 1 (Vahid): the registry's dense variant renamed here with a third lockstep leg; the doctrine comment names the ruler and points at this PR; tests added for the off-doctrine --seed refusal on the national role and for a pre-role size checkpoint refusing to resume; the receipts name R1's attempt id and code state.
  • Suites: test_uk_rowwise_posture.py, test_uk_rowwise_national_role.py (delegation, local staging end to end, remote fake Hub with telemetry under runs/ and the bundle under staged/, dry run, failure marks the run failed), test_uk_rowwise_candidate.py (70), the pre-flight, dense assembler, contract-pin, doctrine, staging and seam suites; ruff check ., tools/ci_test_groups.py --verify, tools/generate_staging_contract_fixtures.py --check.
  • Local CI lanes on the B2 tip: spine-uk 2,638 passed and uk:build 2,294 passed; the one failure, a stale uniform pin in the childcare gate test, is fixed in ec3b224.
  • Parity twin (0ccf8f5, removed with the command): the seam command and the national role agree bit for bit on the synthetic run.
  • Licensed rehearsal, receipted in experiments/823-uk-consolidation-receipts.md. Code state: eba0e152 (this head minus the receipts commit) plus the signed SE 20-30k deferral cherry-picked from the v20 branch (90bdb809, not in this PR; without it the target-fit gate blocks while the weights still compare), so the bit-for-bit result is on that state, not on the bare head. R1, attempt uk-frs-calibration-attempt-20260920T165920Z-5acd7515: the national role on the v20 inputs (spine-s, feed c5e5bf8, no solve flags) reproduced the v20 seam-built dataset exactly (household weights array_equal on 52,846 households, 638 diagnostics rows and losses equal, register f536021bbcd9, six gates passed, an empty override receipt where v20 carried two), 7 min 36 s wall. The same build with remote staging and read-back landed its telemetry (completed, 35/35 uploads, read-back passed) and its bundle under staged/uk-frs-calibration-attempt-20260920T170811Z-ce339e7c/; the fetch tool returned digest-verified files and a byte-equal H5. That rehearsal needed the signed SE 20-30k deferral (90bdb809, on the v20 branch, not in this PR).

Deviations from the reviewed plan

Recorded in repos/uk-823-consolidation-plan.md under B1 and B2: the dense outputs keep the _local family name; the vintage token comes from the pinned FRS release; the posture is bound on the parsed arguments; _stage catches per event; the national role supports --dry-run; an explicit off-doctrine --seed is refused; the feed-pin check raises a ValueError subclass that the (now removed) CLI wrapped; the seam's run config records the line's constant release id; the terminal flush re-opens the session with bounded backoff.

Not in this PR

  • B0 (the score receipt written in the certifier's shape), on its own branch.
  • Certification of a cut: tools/score_uk_national_candidate.py refuses the 119 targets the eFRS incumbent cannot materialize (the v20 head-to-head used the evaluation repo's pruning scorer), so a repository-native certified cut needs a reviewed common register or a pruning scorer in-repo.
  • The publication track (line pointers, registry default, promotion, dashboard) and the pe.uk consumer switch.

🤖 Generated with Claude Code

Added 2026-09-21: the national role evaluates against the incumbent at the end of the build (acd93c12)

María's direction: every national build should evaluate against the incumbent at its end, warn loudly (naming every absent measure) rather than refuse when the incumbent cannot materialize a target, never block staging, and leave a receipt so publication can never run on an unpassed evaluation. The scorer side is on #967 (microcosm.build.uk_runtime.candidate_score, the common-surface scorer whose receipt carries a rule-1 verdict the release-cut certifier requires); this commit is the driver side.

  • Flags (national only; the dense role refuses them): --incumbent-h5, --incumbent-sha256 (together; the digest is verified before anything runs), --incumbent-label (default enhanced_frs_2024_25). The scorer is imported lazily and checked at argument validation, so this branch stands without UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 and refuses --incumbent-h5 with a message naming it until UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 merges.
  • When it runs: after the staged bundle is uploaded and before the telemetry completes (artifacts can only be added to a running run), so the evaluation never blocks staging and its receipt rides the run as the reviewed aggregate artifact artifacts/score_vs_incumbent.json, with incumbent_evaluation started/completed/failed stage events.
  • What it writes: score_vs_incumbent.json beside the outputs (listed in the local sums and under outputs.score_receipt), a stderr warning naming every measure the incumbent cannot materialize and the rows pruned for it, and a manifest evaluation block (status completed/error/not_requested, verdict, rule_1, scored_surface, pruned_measures, pruned_families, receipt, incumbent). An evaluation error is recorded as status: error and warned, never raised: staging and the exit code stand. Without the flags the manifest says not_requested and names the scorer to run before certification.
  • Also: the full compiled register is frozen beside the solve register as national_contract_registry.json (an output, so it ships in the staged bundle): the band edges a pruned scoring surface must never redraw (Fix #792: derive band edges from the compiled register, never the pruned roster #803), and the register a hand re-score passes as --band-edge-registry-json.
  • Tests (test_uk_rowwise_national_role.py): the dense role refuses the flags; the pair is required; the missing-scorer refusal; a fake-seam run with a stubbed evaluator (receipt, manifest block, outputs entry, the warning); an evaluator error recorded with exit 0; a local-staging run whose telemetry carries the artifact and the stage events in order (after dataset_staging, before complete) and whose sums list the receipt; the dry run records the incumbent. Driver, dry-run, pre-flight and dense assembler suites green; ruff check . clean; tools/ci_test_groups.py --verify ok. Runbooks 623/806 and uk-staging-operations.md updated.

A rehearsal build on spine-s and feed c5e5bf8 with --incumbent-h5 (the enhanced FRS 1.57.3 copy), on a scratch branch carrying #967's code commits, is recorded in experiments/823-uk-consolidation-receipts.md (R3) once it completes.

juaristi22 and others added 6 commits September 20, 2026 17:24
…ctrine to the ruled posture (#823)

One driver builds both UK dataset lines. `--release-role {national,dense}`
is now required on tools/build_uk_rowwise_candidate.py: a frozen posture
record (uk_runtime/rowwise_posture.py) supplies each role's doctrine
object, clone count, solve length, learning rate, seed, target-weighting
rule and its admissible overrides, gate scope and posture, Logbook
pipeline and attempt-id prefix, staging operation id, release id and
output filenames. The driver fills the role's defaults into unset solve
arguments, records which were given explicitly, and refuses the other
role's flags by name before any value is range-checked; the manifest
(schema 4) and the dry-run plans record `release_role` and the manifest
`release_id`; the size-checkpoint identity carries the role so a pre-role
checkpoint refuses to resume. The national role is declared and
validated here and raises NotImplementedError after validation: its build
flow (delegation to the calibration seam) is the next increment.

Doctrine: UK_NATIONAL_SOLVE_EPOCHS is 1500 and
UK_NATIONAL_TARGET_WEIGHT_RULE is "family_equal" (ruling 2026-09-20): the
certified-cut posture every campaign national run had overridden to is
the doctrine, so a doctrine run records no overrides; "uniform" stays a
receipted per-run override. The pinned tests move with the constants.

Dense line: the pre-flight and the assembler accept only a manifest whose
release_role is "dense" (a pre-role candidate is rebuilt, never
grandfathered); the published artifact is microcosm_uk_2024_25_dense.h5,
mirrored in the contract as _UK_DENSE_DATASET_FILENAME with a lockstep
pin; the driver's joint-surface outputs are microcosm_uk_2024_25_local.h5
and microcosm_uk_2024_25_local.local_gates.json (the `_local` family stays
because the size evaluator and the pre-flight glob it).

Staging: the driver's default upload cadence is 300 s (the Hub allows
about 128 commits per hour per repository; the v20 run lost uploads at
30 s), a refused stage event is reported and dropped instead of aborting
the build (the #946 follow-up), and add_staging_arguments takes a
per-command default cadence.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The 2026-09-20 ruling moved UK_NATIONAL_TARGET_WEIGHT_RULE to family_equal;
this test still pinned the previous default. Found by the local spine-uk
and uk:build lanes (2,638 and 2,294 other tests green).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…#823)

`tools/build_uk_rowwise_candidate.py --release-role national` now builds
the certified national line by delegating to the calibration seam library
(uk_runtime.calibration_run.run_uk_calibration): the measure resolver is
built from the input file (direct_h5), the solve runs under the seam
doctrine (1,500 epochs, family_equal, learning rate 0.02, seed 0) with
explicit --epochs/--learning-rate/--target-weight-rule/--target-loss-cap
as receipted overrides, the six calibration-seam gates run in-process, and
the seam writes the H5, the diagnostics, the signed gate report, the
build record and the uk/frs Logbook row exactly as the seam command did,
so certification and assembly are untouched. Around it the driver adds
what the dense role has: the pinned input, the frozen
national_target_registry.json (the scorer's register), the rowwise
manifest (build_kind uk_national_calibrated_candidate, release_role,
release_id, the role's doctrine block, the seam's solve and weights
blocks, fit by family, gate statuses, releasable false), staging
telemetry under the attempt id (operation uk_national_calibration,
pipeline uk-frs-calibration) with the two reviewed artifacts, and the
staged bundle under staged/<attempt id>/ in one commit. --dry-run
compiles the register and prints the plan.

Seam library: run_uk_calibration accepts a caller-minted attempt id;
new_uk_calibration_attempt_id, UK_CALIBRATION_PIPELINE and
UK_CALIBRATION_ATTEMPT_ID_PREFIX are public; the committed Chronicle
feed-pin check moves to uk_runtime.chronicle_feed
(require_committed_uk_chronicle_feed_pin, UKChronicleFeedPinError) and the
seam CLI wraps it into its previous SystemExit until it retires.

Staging: the last-mile gap the v20 national run met (three consecutive
rate-limit failures paused remote writes, so complete()'s forced upload
was skipped and the remote progress.json stayed "running") is closed:
completion and failure re-open the best-effort session for a bounded,
backed-off terminal flush (0/15/60 s), warning once if all three miss.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On the seam run suite's synthetic frame and register, seed 0, five epochs,
no staging, tools/calibrate_uk_national_dataset.py and
tools/build_uk_rowwise_candidate.py --release-role national produce
identical household weights (assert_array_equal), identical diagnostics
rows and identical seam build records (calibration, gate summary,
register, input posture, spine provenance, doctrine and its receipt),
differing only in the attempt id and the run config's release id and role
fields. Green on 2026-09-20; this receipt licenses retiring the seam
command in the next commit, which removes the twin with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/calibrate_uk_national_dataset.py and its test module are removed:
the national line is built by tools/build_uk_rowwise_candidate.py
--release-role national, which delegates to the same seam library and was
shown bit-for-bit equal to the command on the synthetic parity twin (the
previous commit; the twin retires here with the command). The command's
behaviours re-anchor on the driver: no --release-id flag (canonical ids
are the role's own), operator exclusions accepted on the staging posture,
a bad input sha refused, the shared staging modes, the committed feed pin
checked before the register compiles and a foreign feed refused (or
recorded when --allow-unpinned-feed says so), and the one Chronicle pin
shared with the local census (now in the chronicle feed tests).

Docs: runbook 623 and runbook 806 §1–§3 name the driver's national role
and its outputs (microcosm_uk_2024_25.h5 and siblings); the staging
operations guide and the README name the two UK commands.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…0 bit for bit and stages to the Hub

R1: tools/build_uk_rowwise_candidate.py --release-role national on the v20
inputs (spine-s 4d9752fd…, feed c5e5bf8, doctrine 1,500 / family_equal /
0.02 / seed 0, no solve flags) reproduces the v20 seam-built dataset
exactly: household weights array_equal on 52,846 households, the 638
diagnostics rows and losses equal, register f536021bbcd9, six gates
passed, an empty override receipt where v20 carried two.

R2: the same build with remote staging and read-back lands its telemetry
under runs/<attempt id>/ (progress completed, 35/35 uploads, read-back
passed) and its bundle under staged/<attempt id>/ in one commit; the
fetch tool returns digest-verified files and a byte-equal H5.

R3: certification is not run yet — the repository scorer refuses the 119
targets the eFRS incumbent cannot materialize; the v20 head-to-head used
the evaluation repo's pruning scorer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Review at fffb021c (Claude Code, high effort; worktree checkout of the six commits on main 18c6d39a; 433 passed, 5 skipped, 0 failed across the posture, national-role, rowwise, preflight, assembler, data-contract, doctrine, staging, feed, national-calibration, size-evaluation and pin suites; ruff check and ruff format --check clean on all 23 changed files; generate_staging_contract_fixtures.py --check and ci_test_groups --verify current; CI 13 green and ten running when I posted; merge-tree clean against main and against #954.)

The consolidation is done the right way round. --release-role is required, the posture is a frozen record with its invariants checked, and the role-specific refusals run before any range check with a nineteen-case national table and a three-case dense table, including the seam's own reason for --release-candidate. The doctrine constants move to 1,500 epochs and family_equal with every pinned test re-pinned rather than weakened, and uniform stays an admissible receipted override. The national role path is what the body says: pin, seam-minted attempt id, telemetry, register compiled with the committed feed-pin check and frozen, run_uk_calibration through the seam's resolver, then the manifest re-bound to the post-finalizer build record; the certifier, the national assembler and the certification module are untouched by the diff. The parity twin compared weights, diagnostics, build-record keys, run config and gate statuses before it was removed with the command, and no live reference to the retired command remains in tools, workflows, the Makefile, CLAUDE.md, the README or the runbooks. My #946 residual is closed: _stage and the three artifact-add sites catch StagingContractError, the upload cadence defaults to 300 s per command, and the terminal flush re-opens the session on a bounded 0/15/60 s schedule with tests.

Should-fix

1. The data registry still names the old dense file. The assembler now mints microcosm_uk_2024_25_dense.h5 and the contract reads that name under a lockstep pin, but registry.py:121 still declares the dense variant as microcosm_uk_2025_dense.h5, pinned by its own test. The body defers the registry to the publication track, but the rename lands here, so a dense cut assembled after merge is unloadable through the registry until that branch lands. This is the #900 writer-and-reader class one hop further out. No dense cut has been assembled, so not a blocker; add the registry line here or a third leg to the lockstep test.

2. The 2026-09-20 ruling has no openable record. national_doctrine.py:61 says "Ruling 2026-09-20 (microcosm#823 consolidation)" with no ruler named, where the line above it says whose the 2026-08-24 ruling was. Issue #823's body carries only the release-id ruling and no comment on it mentions 1,500, family_equal or the date; the plan file is untracked by convention. A doctrine change needs a link — a comment or María's acknowledgement on this PR.

3. Two claimed protections have no test. The off-doctrine --seed refusal on the national role is in the code but absent from the refusal table's tests, and the size checkpoint's role-bearing identity is asserted present but no test resumes from an identity lacking the role and expects the refusal.

Questions

  • The rehearsal ran on code that is not this head. Receipts R1 says the code was the B3 tip plus the signed self-employment 20–30k deferral cherry-picked from the v20 branch, which is not in this PR, so the bit-for-bit reproduction of v20 is on eba0e152 plus one commit that is not here. On fffb021c alone the same inputs are unverified, and R1 gives no attempt id where R2 does. Say so in the body.
  • Schema 4 is documentary. No rowwise-manifest reader compares schema_version before or after this change; only the preflight and the assembler gate on release_role. That is not a Bind UK census households from Chronicle and map NI Data Zones with NISRA's published lookup (#887) #900 defect, since no key was renamed under a reader, but "manifest (schema 4)" reads as if something checks it.
  • The assembler's role gate at line 202 precedes the --allow-missing-staging override at 215, so a pre-lane run now fails on role rather than on missing staging; consistent with "rebuilt, never grandfathered", and worth one sentence where Stage UK rowwise candidate builds: telemetry to runs/ and the dataset bundle to staged/ #946's override is documented.

Nit

A historical evidence record under docs/evidence/uk-region-tier-905/ still names the retired tool; fine as history.


Nothing blocks. 1 is the one to do before merge, because it is the exact defect class this repo has already paid for once; 2 is the register convention; 3 is two tests.

- The data registry's dense variant names microcosm_uk_2024_25_dense.h5
  (the file the assembler mints and the contract reads), with its test
  re-pinned and a third leg on the contract-pin lockstep test
  (assembler, contract, registry): the #900 writer-and-reader class, one
  hop further out.
- The doctrine comment names the ruler and where the ruling is recorded
  (María, 2026-09-20, acknowledged on microcosm#965); the two test
  comments say the same.
- Tests for two claimed protections: the national role refuses an
  explicit --seed that is not the doctrine's (and accepts the doctrine's
  own), and a size checkpoint written before the release role existed
  refuses to resume ("release_role: absent in checkpoint").
- The receipts name R1's attempt id and state the code the rehearsal ran
  on (eba0e15 plus the signed deferral, which is the v20 branch's own
  commit and not in this PR).
- The staging operations guide says the pre-flight's and the assembler's
  release-role gate runs before --allow-missing-staging.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juaristi22

Copy link
Copy Markdown
Collaborator Author

Thanks — addressed in the round-1 commit on this branch; the body is updated for the questions.

Should-fix

  1. Registry: the dense variant now names microcosm_uk_2024_25_dense.h5 here, its own test is re-pinned, and TestDenseLineMirrors.test_dataset_filename_mirrors_the_assembler has a third leg (REGISTRY[("uk", 2025, "dense")].filename == assembler._DATASET_FILENAME), so the reader can no longer drift from the writer. The publication PR carries the same hunk and rebases cleanly over it.
  2. The ruling: national_doctrine.py now names the ruler and where it is recorded — María's ruling of 2026-09-20, given while planning the consolidation; her acknowledgement on this PR is the openable record it points at (the two test comments say the same).
  3. Tests: test_national_role_refusal_table gains the off-doctrine --seed case (--seed != doctrine 0) and the defaults test checks that the doctrine's own seed is accepted; the checkpoint test ends by copying the written checkpoint, deleting release_role from its identity and asserting the resume is refused with release_role: absent in checkpoint and writes no manifest.

Questions

  • Rehearsal code state: right — R1 and R2 ran on eba0e152 plus the signed SE 20-30k deferral cherry-picked from the v20 branch (90bdb809, not in this PR; without it the target-fit gate blocks while the weights still compare). The receipts and the body now say so, and R1 names its attempt id (uk-frs-calibration-attempt-20260920T165920Z-5acd7515).
  • Schema 4: documentary, as you say — no reader compares the version; the pre-flight and the assembler gate on release_role. The body says so now.
  • Role gate before --allow-missing-staging: intended (rebuilt, never grandfathered); one sentence added where the override is documented in the staging operations guide, and the body notes it.

The historical evidence record keeps the retired tool's name as history.

@vahid-ahmadi vahid-ahmadi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing pass at cc23ec06 (Claude Code, high effort; worktree checkout, the response commit read against the dispositions; 157 passed, 0 failed across the rowwise, national-role, posture, contract-pin, registry and national-calibration suites; ruff check and ruff format --check clean on the seven changed files; CI 24 of 24 green; base is main).

All three should-fixes closed, the questions answered where I asked.

1. Verified. registry.py:120 now declares microcosm_uk_2024_25_dense.h5, the same string the assembler mints and the contract pins, its own test is re-pinned, and the lockstep test has the third leg at test_gate_battery_contract_pins.py:412 asserting the registry entry equals the assembler's filename, so the reader can no longer drift from the writer.

2. Verified, with the record being this thread. national_doctrine.py:61 now reads "María's ruling (2026-09-20, acknowledged on microcosm#965)". That makes her acknowledgement on this PR the openable record the constant points at, which is fine as long as it lands here before merge; if it does not, the pointer is to nothing, so I would treat her comment as part of the merge condition.

3. Verified. The refusal table gains the off-doctrine --seed case with the doctrine's own seed accepted, and the checkpoint test copies the written checkpoint, deletes release_role from its identity, and asserts the resume refuses with "release_role: absent in checkpoint" and writes no manifest.

Questions. The receipts and the body now say the rehearsal ran on eba0e152 plus the cherry-picked deferral, with R1's attempt id recorded; #967 carries that deferral, so once it merges the rehearsal is on committed code. Schema 4 is stated as documentary. The role-before-override order is stated as intended in the staging guide and the body.


Approving, on the condition that María's acknowledgement of the 2026-09-20 ruling is on this PR before it merges, since the doctrine comment now names this thread as its record. The consolidation is done the right way round and the retired command leaves no live reference behind.

juaristi22 and others added 4 commits September 21, 2026 16:22
…he build

The national role takes --incumbent-h5 / --incumbent-sha256 (and a label)
and, after the bundle is staged and before the telemetry completes, scores
the finished candidate against it on the surface both can materialize
(microcosm#967's common-surface scorer, loaded lazily so this branch stands
without it): score_vs_incumbent.json beside the outputs and as a reviewed
telemetry artifact, rows the incumbent cannot materialize pruned from both
arms and named on stderr, and a manifest evaluation block with the rule-1
verdict the release-cut certifier requires. The evaluation never blocks the
build: an error is recorded and warned, staging and the exit code stand.
Without the flags the manifest says not_requested. The full compiled
register is frozen beside the solve register as
national_contract_registry.json, the band edges a pruned scoring surface
must never redraw (#803). The dense role refuses the flags.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The reviewed telemetry artifact policy refuses any list of mappings, and
the rehearsal build's receipt was refused on its per-target drift list, so
the artifact never rode the run. The staged copy now drops the drift, the
asymmetries and the resolution receipts and keeps the verdict, the pruned
block and the aggregates; the full receipt stays beside the outputs and in
the staged bundle. The test's receipt carries the arrays.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…certification runs and names what blocks it

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The R3 candidate re-certified with PR #967's four fold-in commits
(stale exclusions retired, June CGT family retired with pass-through
semantics, enum domains on both engines, the build-state half on the
pinned spine frame, the fit-weight collector): 15 passed, 4 failed, 1
evidence absent. Input coverage and both enum gates pass; input-mass
parity fails on the two breaches alone; the weights audit waits on a
spine rebuilt from the fixed collector; the export allow-list and the
two data findings are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Third pass at 43a4acbc (four commits after the approved cc23ec06; CI 24/24; ruff, staging-fixture --check, ci_test_groups.py --verify and pytest over the 13 touched/adjacent suites all clean locally: 291 passed, 2 skipped).

The approval condition is still open. national_doctrine.py:61 says the 2026-09-20 ruling is "acknowledged on microcosm#965", but the only text on this PR that touches it is your round-1 response, which speaks in the third person and points forward to an acknowledgement that hasn't been posted. A one-line first-person comment from you ("I rule 1,500 epochs / family_equal for the national solve, 2026-09-20") closes it; until then the pointer resolves to nothing. My approval at cc23ec06 stands on that condition.

The four new commits are fine, with three notes:

  1. acd93c12 wires --incumbent-h5/--incumbent-sha256 into the national role, but the scorer it loads is microcosm.build.uk_runtime.candidate_score, which exists only on UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967. On this branch alone the flags are refused, so the evaluation path is dead code until UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 merges. It also reaches into module._default_measure_resolver_factory, a private name, and every test here stubs the module, so a rename on UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 would break this silently until a real run. Either import a public name or add a test that imports the real module once UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 lands. I checked the kwargs and receipt keys against UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 c97d2750 by hand and they match today. UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 should merge first.
  2. 6104926e trims target_drift / signed_asymmetries / measure_resolution from the telemetry copy, which should get the receipt past the staging content policy. Two caveats: the test's fake receipt has pruned_targets: {}, so the one block a real run fills with 120 rows is untested, and no real build has run since the fix. The commit message says the full receipt "stays in the staged bundle", but publish_manifest() builds the bundle before evaluate() runs (build_uk_rowwise_candidate.py:2019-2020), so the full receipt never reaches the Hub, only the trimmed telemetry copy. The body and runbooks say "local sums" and are correct; just the commit message overstates.
  3. R3/R4 receipts are honest that both ran on an unpushed scratch branch mixing this PR with seven and then eleven UK national line: the signed v20 deferral, six A16 retirements on measured evidence, and the scoring-path fix #967 commits; neither is reproducible from either PR alone. The remaining certification blockers (export allow-list and dataset name, dfe_education_spending / jsa_income_reported breaches, two all-zero columns, negative consumption, spine rebuild for uk_weights_audit) are register and data calls outside this PR.

Untouched surfaces check out: certifier, national assembler, release_certification.py and national_doctrine.py are byte-identical to cc23ec06. Merge-tree clean against main; conflicts with #967 only on docs/uk-national-release-assembly-runbook-806.md, resolvable as a union.

@juaristi22

Copy link
Copy Markdown
Collaborator Author

For the record, first person: on 2026-09-20, while planning the #823 consolidation, I ruled that the UK national solve runs 1,500 epochs with the family_equal target-weight rule (learning rate 0.02 and seed 0 unchanged; uniform stays selectable as a receipted override). The 2026-09-20 ruling note in national_doctrine.py points at this comment.

@juaristi22
juaristi22 merged commit ac68347 into main Sep 22, 2026
24 checks passed
juaristi22 added a commit that referenced this pull request Sep 22, 2026
…scorer name, gate note and A16 support caveat

Vahid's third pass on #967 (2026-09-22) and his notes on #965.

A2, second half: against the committed register of record the receipt's
reviewed_register.sha256 must be the committed register's digest, so a
receipt scored under another register cannot certify (checked after the
membership refusal; tested both ways inside the entries' window).

#965 note 1: the driver imported the scorer's private
_default_measure_resolver_factory and every test stubbed the module.
uk_default_measure_resolver_factory is the public name, the driver
imports it, and a national-role test loads the real module. #965 note 2:
the telemetry summary is tested with a populated pruned_targets mapping
and asserted free of record arrays.

Nits: the uk_input_mass_parity note recorded the retired
charitable_investment_gifts exclusion as the sole breach; it now records
the 2026-09-22 retirements and the two genuine breaches. The note rides
the policy digest, so the UK gate-battery policy, manifest and
fingerprint pins are re-minted in the data contract and its test (the
scoped part digests are unchanged). The A16 evidence README says which
three retirements were support-signed and that the thin-cell concern
stays a diagnostic, not an error claim.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Sep 23, 2026
…970)

Rebased onto main after #967 retired the June-path CGT family: the
certified manifest is gone (the spine manifest keeps the only
Advani-Summers declaration), the amounts module keeps only the spine
stage, and the CGT manifest tests target the spine stage. This commit
carries what the replay could not: the regenerated coverage manifest
and H2 parity fixture and the recomputed battery and calibration-seam
digests with their data-shard mirrors.

It also fixes the two CI failures the national-role tests (#965) exposed
by running the real seam on a 2023-period frame:

- The seam's projection artifact required the engine, which the
  secrets-free fast lane does not have. Without an engine the seam now
  builds the projection from the gate's pinned growth path and exempt
  amounts (`uk_cgt_projection_from_pins`) and the receipt names that
  source; with an engine it reads the tree and the binding drift-checks
  it against the same pins.
- The exempt amount is pinned by year: 6,000 in 2023-24 and 3,000 from
  2024-25, so a 2023-period base year no longer reads as drift. The
  growth pin gains 2023 alongside.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
juaristi22 added a commit that referenced this pull request Sep 23, 2026
…970)

Rebased onto main after #967 retired the June-path CGT family: the
certified manifest is gone (the spine manifest keeps the only
Advani-Summers declaration), the amounts module keeps only the spine
stage, and the CGT manifest tests target the spine stage. This commit
carries what the replay could not: the regenerated coverage manifest
and H2 parity fixture and the recomputed battery and calibration-seam
digests with their data-shard mirrors.

It also fixes the two CI failures the national-role tests (#965) exposed
by running the real seam on a 2023-period frame:

- The seam's projection artifact required the engine, which the
  secrets-free fast lane does not have. Without an engine the seam now
  builds the projection from the gate's pinned growth path and exempt
  amounts (`uk_cgt_projection_from_pins`) and the receipt names that
  source; with an engine it reads the tree and the binding drift-checks
  it against the same pins.
- The exempt amount is pinned by year: 6,000 in 2023-24 and 3,000 from
  2024-25, so a 2023-period base year no longer reads as drift. The
  growth pin gains 2023 alongside.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants