Repository navigation
Track B B2: floor builder, comparator and scorer (invented-data build) - #526
Conversation
The B0.1 addendum's B2 rules in one place: geometry, seeds and streams; root-parameterised household and design multiplicities; the stratum census, two-cluster guard and design degrees of freedom; t*, the registered standard error, the bound, Monte Carlo and undefined-replicate rules; validity and the INVALID/FAIL/PASS/INCONCLUSIVE conjunction; the ladder inside the six level cells under d1342; tolerances, plain units, exposure labels and report-only intervals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The floor builder is truth-only (addendum section 9, steps 2-6): domain from data, household- and person-split floors, tolerances, se_up from 4,000 household replicates on [20261002, b, 0], the stratum census and nu, the two-cluster stop, and the ladder inside the six level cells on the ruled binding evaluation. Its artifact is exclusive. The comparator reads only the two boundary-2010 floor fields of each selection ledger and prints whether their canonical hashes equal the builder's. The scorer refuses to run without a committed, cleared floor artifact, a registration id and the expected commit. It fits candidate 3 at 2010, projects draws 6200-6219, bootstraps 4,000 design replicates on [20261002, b, 4] and applies section 8's conjunction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Truth tables for every section 5-8 rule; Hypothesis properties for the bound rule's monotonicity, the multiplicities' totals, the ladder's invariants and the outcome's order; differential tests against the planning script (multiplicities at root 20260930 for replicates 0-99, cells, floors, fit, context, copied frames), the ruled-power module (t*, nu, the ladder over all 720 orders) and the selectors (canonical hashes, domain, truth support, person-split floor). The floor build splits into a truth-side measure and a cheap decide, and the registered standard error uses hypot, which Hypothesis showed is needed for se_c >= se_boot at denormal values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…unts Truth tables for the ladder stopping at exactly 0.90 and for floor eligibility at its edges; the household floor is checked against a household split; the artifact's statements carry section 13's items, including the candidate-3 disclosure pointer. The 131 new tests are all unit tier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The registered-settings tests move to the rules file, where the pipeline module's five-seed patch cannot reach them; the missing-design test now drops a person known to be in the truth support. A direct test pins side A as a household split of the full 2011 anchor scored on the full projection. The Track B README says how and in what order the three scripts run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Behaviour unchanged; black had split the condition across lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in the merged B0.1 addendum (#505) and the rest of master. Tier counts resolved as master's plus this branch's 132 unit tests, and verified by collecting each tier: unit 6,898, artifact 3,929, integration_psid 1,346, reproduction_legacy 520, oracle_policyengine 307; total 13,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The build follows the B0.1 addendum as merged (#505). The work came from a GPT-6.1 Sol build lane, whose sandbox could not commit; the operator committed it and added the thread pin. - Element 8's stratum rule replaces the two-cluster guard. One-cluster strata merge simultaneously into the nearest stratum with two or more clusters (lower code on a tie; all into the lowest code if none has two). Strata of three or more clusters get exact Rao-Wu by integer copies at scale L = lcm(n_h - 1), drawing rng.multinomial(n - 1, 1/n). nu is counted after the merges. The floor artifact publishes the census before and after, the merges, L and nu. - The floor builder stops at floor build with WEAK_POWER_OR_VACUITY, naming the cell and quantity, when nu is 0 or a candidate cell's sigma, se_up or tau is zero or undefined (the design's trigger list). - The scorer checks every input before it fits: all 16 planning ratios, the floor artifact's fields, and the design summary recomputed against the committed one. Nothing can abort after the fit begins. - The comparator prints exactly two booleans per ledger: the six M6-retained cells' floor block and their seed 0-4 detail. - The candidate-3 disclosure is held verbatim and pinned. - Threads: every B2 process runs one BLAS, OpenMP and numexpr thread with OMP_WAIT_POLICY=PASSIVE, and up to four worker processes, within Max's 2026-10-11 cap. In the pinned environment candidate 3's projection hangs in the participation gates' HistGradientBoostingClassifier predict_proba with more than one OpenMP thread (reproduced at 2 and 4 threads, PASSIVE and ACTIVE, on invented data). Invariants: merge determinism and cluster conservation; Rao-Wu copies sum to L*n_h per stratum; each cluster's mean copies is L and the replicate-total variance matches the stratified estimator (exact enumeration); L = 1 equals arm D; two fresh processes with different hash seeds give an equal fitted state field by field, equal gate surfaces and byte-identical draws. Unit tier 6,932; total 13,034. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in the EPUF work (#515, #516, #537) and the rest of master. Tier counts resolved as master's plus this branch's 166 unit tests, verified by collecting each tier: unit 7,477, artifact 4,054, integration_psid 1,346, reproduction_legacy 520, oracle_policyengine 308; total 13,705. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The floor builder and the scorer now call b2.thread_settings before they read, check or write anything, so a launch with any thread variable above 1 stops at once instead of hanging later in candidate 3's projection. A regression test drives both entry points with each thread variable set to 4 and requires the refusal before the registration, commit or floor checks run. Moving the guard back after the registration check, or removing it from the scorer, fails the test. Unit tier 7,487; total 13,715. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tempt log GPT-6.1 Sol requested changes on 0e292b0. This commit answers each finding and the CI failures at 03f82d3. - High: the pinned copy_persons refuses 1,000 copies or more, and the stratum rule's scale L can exceed that (strata of 2, 8, 12 and 14 clusters give L = 1,001). b2.copy_persons calls the pinned helper unchanged below 1,000, so frames equal arm F's, and above it runs the same construction at a wider power-of-ten identifier scale. Tests: the differential below the scale, every row and person kept above it, level cells unchanged at scale 1,001, and the full sampler-to-copier path on the reviewer's design. - Medium: section 5's eligibility now comes first. A cell of the six that fails it is scored report-only and the ladder runs on the rest; B2 stops only for nu = 0 or an eligible cell's undefined se_up or tau. - Medium: --workers outside 1 to 4 is refused first in both entry points. - Low: the module README describes the stratum rule, the stops and the thread and worker settings. - The scorer creates runs/track_b_b2_score.attempt.jsonl exclusively before it reads any data and appends each stage, synced to disk; it refuses to start if the log exists. - Serial and pooled replicates are tested equal. - CI: the pipeline tests set the registered thread variables in a fixture; the determinism test skips without populace.fit and reports the probe's stderr; b2.py joins the birth-evidence seal's post-review exclusions, as the other Track B modules did. Mutation checks: three on the copier, five on eligibility, workers and the attempt log; all fail the tests. Unit tier 7,513; total 13,741. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in U2's #524 and the rest of master at 24da3c6. Tier counts are master's plus this branch's 202 unit tests, verified by collecting each tier: unit 7,537, artifact 4,080, integration_psid 1,384, reproduction_legacy 520, oracle_policyengine 308; total 13,829. The README table, which master had left at older figures, is set to the collected counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Opus 5.5 round-2 review approved 1d1ce71 with low findings only. B2 registers on this PR's merge commit, so they are folded in now: - L1: the scorer's data-free checks (the scoring inputs and the NAWI read) run before the attempt log is created, so an operator error there leaves no attempt behind. - L2: the pipeline tests point the scripts' outputs and attempt log at their own directory, so B2's committed run files cannot break them. - L3: a test pins the log's place: after the data-free checks, before any PSID data is read. - L4: a test runs the scorer's own replicate at L = 1,001. - L6: POPULACE_FIT_N_JOBS must be 1 to 4. Unset, populace-fit's forests use every core; protocol v2 pinned 4. Forest seeds are per tree, so the count does not change a fit. - L7: the log's directory entry is synced to disk as well. - L8: the birth-evidence reachability test names track_b.b2. - Wording: the floor builder's docstring, the pipeline test header and the README describe the eligibility-first stops; UTC uses datetime.timezone for Python 3.10. Mutation checks: the log opened before the checks, an unset job count accepted, and the scorer copying through the pinned helper each fail the tests. Unit tier 7,545; total 13,837. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The delta review of 485645d (approve) noted that the floor builder's and the scorer's docstring launch examples did not set POPULACE_FIT_N_JOBS, which thread_settings now requires, so a copied command would be refused. Both examples set it to 4, and thread_settings' docstring names it. Comments only; no behaviour changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…igma GPT-6.1 Sol's round-2 review (request changes, medium) found that B2's eligibility still required sigma > 0, which section 5 does not list. A degenerate floor (every split score zero: mean, SD, sigma and tolerance all 0) was then dropped as ineligible, and the other cells could clear, where the design's trigger list calls an uninformative tolerance WEAK_POWER_OR_VACUITY. A zero sigma with a nonzero tolerance would also have reached the ladder's tol/sigma ordering. - b2.floor_eligible is section 5's rule: every seed defined and at least 20 events. The planning script's floor_eligible is unchanged; a differential test checks B2's rule plus sigma > 0 equals it. - The floor builder's stop checks on eligible cells take sigma back with se_up and tau, so a zero or undefined sigma stops B2 at floor build instead of dropping the cell. Ineligible cells (seeds, events or planning values) are still scored report-only and never stop B2. - The seal comment names the comparator as well (round-2 low finding). Tests: a consistent zero floor and a zero or undefined sigma on an eligible cell stop B2 before the ladder; a cell failing on seeds or events is report-only even with zero sigma and se_up. Mutants: sigma back in eligibility, and sigma left out of the stop checks, both fail. Unit tier 7,547; total 13,839. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GPT-6.1 Sol's round-3 review (approve) noted two wording lags: the eligible-cell stop list omitted sigma, and the attempt log was said to precede "any data" although NAWI is now read first. The README now gives section 5's eligibility, the sigma, se_up and tau stops, and the log's place after every data-free check and before any PSID read. Docs only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged with a merge commit at the reviewed head ( Gates at merge
Independent reviews Each reviewer worked on a cleaned copy of the head, with the Q6 exclusion list removed, and read code only.
Verification
Next B2 registers on issue #42, pinning
The single-thread finding is in the PR body: candidate 3's projection hangs in the gates' |
|
Correction to the thread finding in this PR's description and the audit comment above. On 2026-10-13, probes of candidate 3's fit and projection on invented data with more than one OpenMP thread stalled in the gates' On 2026-10-15, at the merge commit
A 4-thread probe in the earlier environment also completed, in 59 s. So the stall is intermittent, not "5 of 5", and its cause was not identified. B2 keeps one thread per process: it completed in every run, it was the fastest, and its cross-process determinism is tested. B2's registration on #42 gives this account and keeps the logs. |
…tiers Master gained #526 (Track B B2) and #529 (Track B R3) since this branch's base (24da3c6). Only tests/tier_counts.json and tests/README-tiers.md conflicted; both are rewritten from a whole-suite collection of the merged tree (15,386 tests, each with exactly one tier): unit 8,956, artifact 4,201, integration_psid 1,401, reproduction_legacy 520, oracle_policyengine 308. That is master's counts plus this branch's per-commit deltas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
B2's floor builder, comparator and one-shot scorer, built to the B0.1 addendum as merged in #505 (
docs/design/track_b_b0_1_addendum.md, sections 4-9 and 13). This is an invented-data build: no test sets the PSID directory, opens a PSID file, or reads a selection ledger or a B1 output, and nothing here has run on PSID data. B2 registers on issue #42 pinning this PR's merge commit, and only then runs, in the order section 9 sets.What it builds
src/populace_dynamics/track_b/b2.pyt_star; the registered standard error; the bound, Monte Carlo and undefined-replicate rules; validity and the INVALID → FAIL → PASS → INCONCLUSIVE conjunction; the ladder inside the six level cells (d1342); tolerances and their plain-unit statements; exposure labels; report-only intervals; the candidate-3 disclosure, verbatim; and the thread guard.scripts/track_b_b2_floor.pyb2_read_set_sha256's 80 files and checks each opened file's hash. It checks the domain and support counts against the frozen record, then computes household- and person-split floors (seeds 0-99), tolerances and se_up (4,000 household replicates on [20261002, b, 0]). It publishes the stratum census before and after the merges, the merges, L and ν. It applies section 5's eligibility first, exactly as written (every seed defined, at least 20 events, planning values present): a cell of the six that fails it is scored report-only. It stops at floor build withWEAK_POWER_OR_VACUITY, naming the cell and quantity, when ν is 0 or an eligible cell's σ, se_up or τ is zero or undefined. An uninformative tolerance stops B2; it never drops an eligible cell. Otherwise it runs the ladder over the eligible cells on the ruled binding evaluation, and writes one exclusive artifact (runs/track_b_b2_floor.json).scripts/track_b_b2_compare_floor.pyscripts/track_b_b2_score.pyruns/track_b_b2_score.attempt.jsonlexclusively and appends each stage, synced to disk with its directory entry, so an interrupted run leaves its last stage on disk. It refuses to start if that log exists. Its output (runs/track_b_b2_score.json) is exclusive.Element 8's stratum rule
rng.multinomial(n_h − 1, 1/n_h)over its clusters, sorted by original (stratum, cluster), and each draw counts L·n_h/(n_h − 1). L is lcm(n_h − 1), and every stratum's copies are scaled by L. Strata are visited in ascending merged code. When every stratum has two clusters, L = 1 and the multiplicities are arm D's.b2.copy_personscalls the planning script's pinnedcopy_personsunchanged while every count is below 1,000, so frames equal arm F's. Scale L can need more copies: merged strata of 2, 8, 12 and 14 clusters give L = 1,001. For those it runs the same construction with a wider power-of-ten identifier scale. Only the identifiers' encoding differs.Threads
Every B2 process runs one BLAS, OpenMP and numexpr thread with
OMP_WAIT_POLICY=PASSIVE, and the replicates run in up to four worker processes. That is within Max's 2026-10-11 cap of four threads on the shared host.b2.thread_settingsrefuses any other setting, and also requiresPOPULACE_FIT_N_JOBSfrom 1 to 4: unset, populace-fit's forests use every core, so protocol v2 pinned 4. Forest seeds are per tree, so the count does not change a fit.b2.require_workersrefuses more than four workers. Both entry points call them first, before reading, checking or writing anything. A regression test drives each entry point with each thread variable set to 4 and requires that refusal.The reason: on 2026-10-13, in B2's pinned environment, probes of candidate 3's projection loop with more than one OpenMP thread stalled in the participation gates'
HistGradientBoostingClassifier.predict_proba. One sat at 0% CPU for more than ten minutes, and four more were stopped by 60- to 150-second timeouts, at 2 and 4 threads under PASSIVE and ACTIVE, on invented data. Correction, 2026-10-15: at the merge commit, in B2's registered runtime, the same probes completed at 2 and 4 threads, in 40-51 s against 16 s for one thread. A 4-thread probe in the earlier environment completed too, in 59 s. The stall is intermittent and its cause was not identified. One thread per process completed every time and was the fastest, so B2 keeps it. Field by field, the only thread-dependent part of a fitted gate is the thread count HistGradientBoosting records on its bin mapper (_BinMapper.n_threads). That counter is why the pickle-hash fit signatures differed between 1 and 4 threads, while the 20 projected draws were byte-identical. Candidate 3's frozen runner pins 8 threads and ACTIVE, but B2 projects through the selectors'_project, as protocol v2 did, so that guard does not apply.Invariants (load-bearing logic)
tests/test_track_b_b2_threads.py).Differential tests
design_multiplicitiesfor replicates 0-99. The household multiplicities equalanchor_multiplicitieslikewise, and nothing in B2 readsBOOTSTRAP_ROOT_SEED.design_summary,floor_eligible, cell values, the household floor, the fit, the context, the projections and the copied frames all match. With the same multiplicities, the scorer's gaps equal arm F's.t_star, ν and the ladder match. Over all 720 pruning orders the ladder ends whereladder_outcomesdoes.select_m6_qstar_train_only._boundary_contextat boundary 2010, so the builder's hashes are comparable with the ledgers' floor fields.Tests and tiers
unittier.test_track_b_b2_rules.pyhas 87,test_track_b_b2_pipeline.py97,test_track_b_b2_design.py19,test_track_b_b2_compare_floor.py7 andtest_track_b_b2_threads.py2. All 212 pass with-n 4, both at the registered thread settings and with no thread variables set, as on CI. Withoutpopulace.fit, as on CI, the cross-process determinism test skips.addendum_power,addendum_record,counts,planning_valuesandruled_powerpass on this head: 243 tests. The other four B0.1 files rescan files on the Q6 exclusion list, so this build does not run them. This PR changes no file they test.24da3c61, checked bypytest --collect-only -q -m <tier>: unit 7,547, artifact 4,080, integration_psid 1,384, reproduction_legacy 520, oracle_policyengine 308. Total 13,839, which is master plus this PR's 212 unit tests. The README table, which master had left at older figures, now matches.b2.pyjoins the birth-evidence seal's post-review exclusions, as the other Track B modules did.Mutation checks
Each mutant changes one fragment of the code under test. The named tests then run and must fail, and the source is restored.
61879ed6, 28 of 28 killed (Subfleet job20261013-183728-b2-mutants):<, Monte Carlo tol/5, 5% undefined;7a1dd5fd, 2 more killed: σ > 0 restored to eligibility, and σ left out of the eligible-cell stop checks.485645d6, 3 more killed: the attempt log opened before the data-free checks, an unsetPOPULACE_FIT_N_JOBSaccepted, and the scorer copying through the pinned helper.1d1ce716, 8 more killed:03f82d3d, 2 more killed: the floor builder's guard moved after the registration check, and the scorer's guard removed.61879ed6, 15 more killed:6b89f658, the first build's 59 of 59 killed. M13 and P10 targeted the two-cluster guard, which the stratum rule has since replaced.src/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pysrc/populace_dynamics/track_b/b2.pyscripts/track_b_b2_compare_floor.pyscripts/track_b_b2_compare_floor.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_floor.pyscripts/track_b_b2_score.pyscripts/track_b_b2_score.pyOpen points the registration settles
These were flagged by the builds. The registration on #42 states each before any run:
WEAK_POWER_OR_VACUITYunder any reading.runs/track_b_b2_floor.jsonandruns/track_b_b2_score.json.Blindness
~/microcosm-launch-evidence/file and no B1 output was opened.axiom: n/a: evaluation-gate infrastructure, no policy encoding.
🤖 Generated with Claude Code