Skip to content

Federal SSI interface and source-to-input contract (SSI0) - #573

Merged
MaxGhenis merged 36 commits into
masterfrom
ir/ssi0-20261024
Nov 2, 2026
Merged

MaxGhenis merged 36 commits into
masterfrom
ir/ssi0-20261024

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

This is milestone SSI0 of the income-and-resources design (#559: §3.3 and the SSI0 row of the milestone table). The third review round approved 48a71983. Later rounds hardened how the inventory reads each variable. The eleventh approved 691111f0 with three low findings and four notes; 4150b7d4 answers them, and f92719ce recounts the tiers. The twelfth, a delta review of f92719ce, asked for revision, with three medium findings; cba389ab and cb728630 answer it, and 208b4d49 recounts the tiers. The thirteenth approved 208b4d49 with three low findings and seven notes; 146c3723 narrows the claims it falsified, and 56bbcde8 carries the latest merge of master and tier recount. The fifteenth, a delta review of 56bbcde8, asked for revision, with two medium findings; c865dce1 answers them. The sixteenth, a delta review of c865dce1, approved it with no finding.

What it adds

An annual federal SSI interface to the PolicyEngine release that the latest policyengine (6.10.2) certifies: policyengine-us 2.2.1 and policyengine-core 3.33.3. It ships with a complete source-to-input contract, published before any SSI computation.

  • Interface (src/populace_dynamics/income_resources/ssi/):
    • typed person, marital-unit, household, account and case records;
    • input validation;
    • a runner that gives every case one counted outcome, accepted or refused;
    • a worker that runs in a separate interpreter and calls only the public policyengine interfaces. It never imports policyengine_us internals.
    • Four or more cases that share a year, policy, geography and outputs run in one dataset calculation. Entity IDs get per-case prefixes, and callers' IDs and row order are restored. If that calculation fails, each case is rerun alone, so a case that fails refuses only itself.
  • Pin:
    • pin.json records the three primary versions, wheel hashes and RECORD hashes;
    • environment_wheels.json records all 89 installed distributions;
    • docs/analysis/ssi0/requirements-macos-arm64-py313.txt is the hash-locked environment;
    • the runner refuses any installed version that differs from the pin;
    • the RECORD digests cover entries inside site-packages only, so the same release installed at another path matches. The build's first pin hashed whole RECORDs, whose console-script shebangs embed the interpreter's path. 2dee2fc4 fixes this and adds two properties.
  • Inventory (inventory.json): 52 federal SSI variables, an 86-variable closure, 41 inputs and 24 parameters. It was regenerated byte for byte by scripts/income_resources/inventory_ssi.py and compared with PE-US 2.18.0. Both releases have the same active chain, inputs and parameters.
  • Contract (input_contract.json, version ssi0-v1): each of the 41 engine inputs and 12 context rows gets one decision per starting population (PSID, SIPP, Microcosm's frame). The decision is a source, an opted-in assumption with an audit ID, or a refusal. scripts/build_ssi_input_contract.py reproduces it together with the review table in docs/analysis/ssi0/input_decisions.md.
  • Captures: 119 plain-request captures (legal sources, release metadata, PyPI records) with URL, UTC time, size and SHA-256 (docs/analysis/ssi0/captured_sources.md). Each capture folder has a .gitattributes with * -text.

Refusals (RULES_ENGINE_GAP)

  • Resource deeming is absent in the certified release. Mixed-age, noncitizen and non-take-up married pairs refuse, as do married tax-dependent pairs.
  • Retirement accounts: an account refuses when its balance is positive or it is eligible for periodic payments. SSI2 settles their treatment from POMS SI 01120.210.
  • Monthly periods: the public interfaces are annual, so results are annualized frozen-state amounts. The annual-equals-twelve-months differential is left to SSI2.
  • Years before 2022: prepare accepts any four-digit year, and the worker raises on each year before 2022, so such a case ends in a counted refusal with no result. 2022 gives the first result.
  • State supplements are outside the admitted outputs.
  • Overrides: only the FBRs, resource limits and income exclusions can be overridden.

Invariants

  • Every inventoried input has exactly one decision per population.
  • No missing or unknown input reaches an engine default. Explicit zeros survive.
  • Household, marital and tax links partition people. Resources stay with their owners.
  • Every attempted case has exactly one counted outcome, and it does not depend on which other cases share its batch.
  • An enum input is admitted exactly when it names a member of the pinned enum.
  • The inventory reader (scripts/income_resources/inventory_ssi.py):
    • Every variable and parameter in the federal SSI trees appears. A .yml file in the parameter tree refuses: the engine loads one as a parameter, unless its stem is index, reference or __pycache__, and the table would leave it out.
    • The variable files are those the engine's directory walk loads. Its globs skip dot names, and it reads as metadata only the path it joins for a folder's own __init__.py, so a file whose name merely ends in __init__.py is a variables file. A folder whose path has a glob character (*, ? or [) refuses, since the walk globs the whole path and its glob of that folder can read another folder's files. For the pinned release, an oracle test checks the reader's file index against the country system's own walk, file for file and in order. A dependency whose stem names more than one file refuses, and so does a variable name read from two files, which the engine refuses to register twice. Every dependency reaches another inventoried variable or an explicit input.
    • A variable that is not a boundary is an input exactly when it has no formula and sets neither adds nor subtracts, as the engine's is_input_variable has it; a defined_for or a label plays no part. So the contract supplies every variable the engine holds as an input and, boundaries apart, none that the engine calculates. The inventory still follows an input's dependencies, so each resolves.
    • Every module the reader reads may import only three things: the model API's star import, names from modules under policyengine_us.variables., and Simulation from policyengine_core.simulations. This covers variable modules, followed modules, and the package inits their imports run.
    • Such a module binds neither Variable nor Enum, in any form. The reader trusts each spelling to name what the model API's star import binds only because no module it reads binds it. So a base spelled Variable marks every variable class in the module, and a class on Enum is a core Enum, never a variable.
    • The part of each such module that runs at import calls nothing, applies no decorator, stores or deletes no item, and assigns nothing in place. That part is the module level, class bodies, decorators, defaults, annotations and type parameters. Such a module also stores no attribute and names no reflective builtin, frame attribute or dunder name. Every variable class in it, whether or not the closure reads it, has no type parameters and a body of a leading docstring, single assignments to attributes the engine's constructor reads, and undecorated formulas, each formula name defined once, and it declares at most one of a formula, adds or subtracts, and uprating, as the engine's check_computation_modes requires. So no variable class overrides a Variable method. Otherwise the inventory refuses.
    • Followed imports are resolved as the import system resolves them, by PathFinder.find_spec in the reader's own interpreter, with its path hooks and suffixes; no meta path finder is asked. Namespace folders pass. Every other step must be .py source loaded by SourceFileLoader, read from that origin; anything else refuses. The reader also refuses when its interpreter would match file names without regard to case, as PYTHONCASEOK makes it on a case-insensitive platform without -I or -E. The documented command runs it with -I.
    • Each value_type, entity and period is one plain assignment, of a name its module never binds.
    • Each default is absent; a literal of its primitive type, where an int for a float is admitted only when float(v) == v; or a member of its statically read enum class. The inventory reads an enum input's members only from a module whose own code cannot change them, and no member takes the name of the class's encode method, which formulas and the engine call.
    • For a variable that is not a boundary, adds, subtracts and defined_for, which name the variables the engine reads for it, are each a string literal or, for the first two, a list or tuple of them. A boundary keeps any value, since the reader bypasses its dependencies; in both releases the one such value is social_security's computed adds.
    • A defined_for, and a list item without a period, names a variable, whatever file defines it, so a name the file index misses refuses as unresolved. A defined_for must name a variable of a numeric type, as the engine requires when it registers the variable.
    • A string adds or subtracts, and a list item with a period, names a parameter, which the reader resolves as the engine's get_parameter does. It splits the name on periods; an empty part refuses; each part must be the exact child name, case included, of one entry of the parameter folder before it; the name must end at a .yaml file that the engine builds as a dated Parameter; and anything else refuses with a ValueError. A string's parameter must list variable names on every date, and the record holds their union over all dates, where the engine reads the list at the start of the period and skips a date marked expected. A mapping marked expected: true that holds a list joins that union. A name that names its own variable, directly or through a parameter's list on any date, refuses: the engine's calculation of a variable that names itself at the period never ends, and the other dates refuse in the safe direction. A formula's parameter prefix resolves by the same exact names to a .yaml file or a folder, or refuses. The resolution also refuses, in the safe direction, a key inside a YAML node, a folder or a .yml file that a string names, a file of dated keys without values, a bare expected string, and a parameter the engine builds rather than loads. Every parameter file the reader reads has distinct keys, as the engine's YAML loader requires.
    • The reader decodes source as Python decodes it. The output is deterministic, whatever the hash seed: a body literal counts by the source alone, and the walk takes files in a fixed order.
    • Over the Hypothesis domain, for every invented module the reader admits, the record equals what Python binds. For the pinned release, the oracle checks each record's value_type, entity, period and default value against what the engine loads; the type of the engine's default against the type the engine's conversion gives the record's default (an int, bool included, becomes a float only as the explicit default of a float variable); each enum variable's members; whether the engine holds the record to be an input; and that the adds, subtracts and defined_for the engine holds, and the names a string's parameter lists on any date, are on the record. The engine holds one float for an explicit 40 and 40.0 of a float variable, so a test that runs no engine also compares each record's default, by value and type, with the literal the pinned source binds, or with the core type default where it binds none. A core-harness oracle, which builds no country system, loads each invented naming, input-rule and load-time form in the pinned policyengine_core and shows that it raises, refuses to load or reads as the reader's record or refusal says.
    • For the pinned release, the engine's trace agrees with the record over nine invented households, with every input the contract names set. Each household calculates the 52 federal SSI variables, and the test asserts that its targets number federal_ssi_variable_count. It runs once with no reform and once under the reform of all seven overrides the runner admits, and the reformed tree holds the reform's individual FBR. The engine reads exactly the listed variables and seven names of its own input route. system.py moves the values of employment_income, self_employment_income and sstb_self_employment_income to their _before_lsr variables. The adds of employment_income sums its _before_lsr variable and a behavioral response, and that response reads labor_supply_behavioral_response. Every listed name is read. Every formula edge from a record that is neither an input nor a boundary is in the record's dependencies, apart from a variable reading itself. Every parameter the tracer records is on the record or a gov.abolitions.<name> gate, which the engine reads before it calculates each variable that has one. The tracer records only a formula's reads, so a parameter that adds or subtracts names does not show there; the attribute oracle above compares those. Under the reform a recorded parameter may also sit under gov.simulation.labor_supply_responses., which the behavioral response reads before it gives 0. The test asserts that the response stays 0 on both traces and that no admitted override sits under that prefix.
    • The reader's header states four limits.
      • A record's dependencies are what a variable's adds, subtracts and defined_for name, as above; the first argument of an entity accessor call; and the string literals of its body and of the federal SSI helpers it calls that equal the stem of a file whose name has no leading underscore or the name of a variable class in the same module, by the source alone. A formula's read of its own variable, which may be at another period, is no dependency. A formula that reaches a variable through a function or constant its module binds, through a parameter's values, or through a name it builds reads a variable the record does not list, and so does one that passes a literal to anything but an accessor when the class of that name sits in a file of another stem. A literal no code reads, such as a label that equals a file's stem, adds a dependency the engine does not read. The reader bypasses a boundary's dependencies, so a literal defined_for on a boundary, which the engine applies when it runs the boundary's adds, stays unread, and so does its type. The reader follows an input's dependencies, though the engine reads none of them for a value the contract supplies. The safe-direction refusals above hold in neither release. The trace test checks the pinned release's records over invented households. It builds policyengine_us's Simulation itself, where the runner's calculate_household calls compile_reform (which gives no reform for a case without overrides, and each scalar override from 1 January of the year), passes spm settings, builds one marital unit of every person, and calculates at the year, where the test calculates MONTH targets at 2026-01 only. Those differences, a code path the households don't reach, the dataset route's simulation and any other release stay outside that test. In both releases the only names a closure variable's body loads from its module are its enum classes, Simulation and _apply_ssi_exclusions, an SSI helper imported under its own name.
      • The engine's directory walk also runs every module under policyengine_us/variables outside the closure, and such a module can change what the engine loads; the reader does not read those modules, and only the pinned-engine oracle covers them.
      • The engine also loads every file under parameters/, and one it cannot load stops it, while the reader reads only the files it lists or resolves. Nor does the reader check every rule the engine applies as it loads a variable: it admits a variable class with no label, a formula name the engine cannot parse, a class bound a second time at module level and a metadata.yaml in a parameter folder that a name passes through, each of which stops the engine. A release the engine does not load gives no record to compare, and only the pinned-engine oracle shows that the pinned release loads.
      • Python's source loader can also run a module's cached bytecode instead of its source: the file that importlib.util.cache_from_source names, in __pycache__ or under sys.pycache_prefix when that is set. It runs a timestamp file whose recorded modification time and size match the source's, and never compares that file's code with the source. It runs a hash-based file unless it compares the file's recorded hash with the source's and they differ, and it compares them, under --check-hash-based-pycs, for a file marked checked in the default mode, for every file under always, and for none under never. The reader reads only source, so only the pinned-engine oracle covers cached bytecode too.

Tests

Tier Added
unit 790
oracle_policyengine 29
  • Unit: 790 passed: contract 20, runner unit 41, inventory 729.
  • Oracle tests:
    • they skip unless POPULACE_DYNAMICS_PE_US_PYTHON_SSI0 names the pinned interpreter (fallback ~/.venvs/policyengine-py-6.10.2/bin/python), and the name contains the classifier's oracle substring;
    • engine 25 and dataset engine 3: 28 passed on the pinned interpreter at c865dce1, each module whole;
    • tests/income_resources/test_ssi_static_offset.py (1 test) holds the static-offset differential, moved out of test_ssi_engine.py so that the engine checks import nothing from the estimates package. It imports estimates/adjusted_poverty.py inside the test body. CI collects it and skips it, because CI has no SSI0 interpreter. It ran on the pinned interpreter at 765c4879, 2864d622, ff70470a, 691111f0, f92719ce and 208b4d49, each time in a throwaway clone with output kept off-screen: 1 passed. It does not run in CI.
    • The moved test's values: the policy is ssi_invented.INVENTED_POLICY (FBRs, exclusions, earned-income share and resource limits); the five Social Security amounts and the 25% cut share are invented; the income year is 2026, as in the other invented cases; the two-cent tolerance follows test_ssi_engine's federal invariants; and every expected offset is the pinned engine's own result for an invented case. Its only constants that also appear in adjusted_poverty.py are the integers 0, 1 and 2 and the fu key passed to _ssi_response.
    • tests/estimates/test_birth_evidence_artifact.py gives 12 passed and 1 failed in this branch's sparse checkout, in test_post_review_exclusions_are_unreachable_from_birth_evidence. CI's full checkout runs that module, and its Tests run at f92719ce passed.
  • Mutants and the parent check, on the reader and inventory tests at cb728630, each mutant run over the whole inventory module:
    • this round's 37 reader mutants (mutants_r14.py), one or more for each rule or guard the round adds, with round 12's B3, B7, B9, B10, B14 and B19 ported to this round's loop. At cba389ab, O3, P14, Z1 and B9 survived. O3 and P14 showed test gaps, Z1 changed only the exception type, and B9 changed no record of either release but admitted a boundary's adds that names itself or an absent parameter. cb728630 adds a test for each, and all 37 fail at that head;
    • the trace-test mutants: TM1 (no root filter), TM2 (the plain trace in place of the reform's), TM3 (no gate prefix) and TM8 (an empty reform) each fail test_engine_trace_reads_only_what_the_inventory_lists;
    • round 13's 15 mutants: this round's code replaced the text of 11 of them. Their ports and the port of round 10's C1 (r13p, 12 mutants) all fail, and so do the other 4;
    • round 11's 17 mutants, one or more per rule that round added, with round 8's S11, S12, M19 and P4 ported to that round's code: all 17 caught;
    • the round-10 review's Y1–Y7: 6 caught, Y1 and Y3 among them. Y5 survives in the safe direction: it refuses whenever PYTHONCASEOK is set, even under -E or -I, and so only over-refuses;
    • round 10's 10, less C1: of the 9, 6 caught; C4, C5 and G2 survive as equivalent, as before (C4 and C5: module_imports already refuses a class that is not a top-level statement subclassing Variable or Enum alone; G2: with no glob character in the folder's path, a match named __init__.py is the joined path);
    • the round-9 review's MY1–MY7: all 7 caught;
    • round 9's 41: 37 caught, and I7, I10, F3 and F4 survive as the known equivalents;
    • round 8's 103, less S11, S12, M19 and P4, whose code round 11 replaced and whose ports N5, N6, N2 and F2 run in round 11's set: of the 99, 91 caught, and the 8 survivors (S3, C4, C5, PV2, PV3, PV4, M11 and M17) are the ones earlier rounds judged equivalent;
    • at cb728630, 58 of the 729 inventory tests fail against f92719ce's reader, the same 58 in each of Hypothesis seeds 0, 1 and 2. They sit in 17 of this round's 20 new test functions, and no older function fails.
  • Fixtures: all invented.
  • Tier counts: the last commit adds SSI0's modules to master's counts at 18082859: unit +790 (20,454), oracle_policyengine +29 (337), with artifact 4,271, integration_psid 1,471 and reproduction_legacy 520, 27,053 in all. CI's tier-policy test passes on those counts. The recount takes the static-offset test from its source, as one unparametrized function.

Since the build

  • 2dee2fc4 makes the installation RECORD digest skip entries outside site-packages.

  • 14febfdb merges origin/master at fe5ab5ab cleanly.

  • d037e91a renames the pinned copy of policyengine-us 2.2.1's ssi_if_takes_up.py to .py.txt, because black and ruff read every .py file and the lint job failed on it. Its bytes, size and SHA-256 are unchanged, and both capture manifests and the captured-sources table name the new file.

  • bde9d3dd keeps the birth-evidence seal. The twelve new files under src/populace_dynamics/income_resources/ are listed in POST_REVIEW_SOURCE_EXCLUSIONS and in the test's expected tuple, and a new assertion checks that none of the SSI modules is reachable from the birth-evidence reducer.

  • black and ruff are clean. The seal, U2-isolation and lane tests pass locally (83 passed, with the oracle tests on the pinned interpreter). tests/test_tier_policy.py is expected to fail until the tier-count slot.

  • The independent review at bde9d3dd (GPT-6.1 Sol, round 2) found one medium problem and asked for revision. When a pooled calculation failed, the worker copied its error to every case in the pool, so one invalid case refused every valid case pooled with it.

  • 48a71983 fixes it:

    • after a pooled failure, the worker reruns each case alone, and only a case that fails alone reports an error;
    • the inventory now reads each enum variable's member names from the pinned source, and the contract row for immigration_status carries them, so an invalid name refuses its own case as INPUT_CONTRACT_GAP before dispatch;
    • the regenerated inventory differs from the old one only by those member lists, and the contract only by the enum row's list;
    • new tests: a pool-boundary regression, a Hypothesis property that a case's outcome does not depend on its batch companions, enum membership properties, inventory extraction tests, and an oracle test that sends a pooled batch with one invalid request straight to the pinned engine;
    • with the old worker restored, the property finds the minimal counterexample (four pooled requests, three invalid, the valid one refused), and the regression and enum tests fail.
  • At 48a71983, lane, seal and U2-isolation tests give 86 passed, with the 8 oracle tests skipped. The 8 oracle tests pass on the pinned interpreter. black and ruff are clean.

  • The round-3 delta review (GPT-6.1 Sol, at 48a71983) approves, with no high or medium finding. Its probe ran the worker's parent and child control flow over 162 batches, with the failing case at every position for sizes 1 to 11 and at the first, middle and last positions for sizes 12 to 16. Each batch left exactly one refusal and kept the valid outcomes, case IDs, order and accounting.

  • Its one low finding: 48a71983's message says every listed invariant has a property test, but the inventory's refusal of an enum input whose members it cannot read had only a fixed example. fdd85c6e adds two Hypothesis properties to tests/income_resources/test_ssi_inventory.py: invented enum members round-trip from source, and an enum input whose class is absent, empty or not an enum refuses the inventory. It changes no other file.

  • At fdd85c6e, lane, seal and U2-isolation tests give 88 passed, with the 8 oracle tests skipped. black and ruff are clean.

  • b8d9a68a closes three ways the enum reader could disagree with Python: unsupported assignment forms in the class body, other bindings of the class's name, and a default outside the class's members. None affected the pinned release; the regenerated inventory, contract and decision table were byte-identical.

  • The round-4 delta review (an Opus 5.5 reviewer, at b8d9a68a) asked for revision, with two medium findings:

    • methods were skipped as non-members, but a decorator can make one a member and an __init__ hook can drop members;
    • the binding count read only top-level statements, and the variable's own body was never checked. A class in an if block, a walrus, a match capture, a global declaration in a function or class, a guarded or aliased import, a star import after the class, or a second binding of possible_values in the variable's body could each change the class while the reader recorded the original members.
      Its low findings: an alias passed the contract although Enum.encode accepts only canonical names; Enum was matched by spelling; and one refusal test passed only because of the default check.
  • 08fdaaf1 fixes these, and a further gap found while writing the fix: module code could reach the variable itself, by an attribute store such as invented_status.possible_values = Other, a decorator, or a rebinding of the variable's name.

    • The reader counts every binding site of a name in any scope, and binds the class and the variable to one site each.
    • The variable must bind value_type, possible_values and default_value once each, by plain assignment.
    • A module is refused if it imports anything but the model API's star import before the class, binds Enum, uses a reflective builtin or frame attribute, or names anything with a leading underscore (which covers a function's __globals__). Round 5 showed this held only for Name and Attribute nodes; see below.
    • Outside its body, the class may be read only as possible_values, the default, a member or encode.
    • Methods, aliases, equal values and chained targets in the class body are refused.
    • The oracle now loads the engine's country model and checks each enum variable's loaded class: source path and hash, base, members against canonical names, and default. Code that changes a class from another module would show there.
  • Tests at 08fdaaf1:

    • a Hypothesis differential of 400 invented modules against Python, each with at most one refused form among admitted ones. Of 2,000 drawn examples, 819 were read and compared in that run (not reproducible, since Hypothesis draws differ between runs; see below);
    • each refused form refused on its own, and Python's answer shown to change for each form marked observable, including (lambda: None).__globals__[...] and a generator frame's f_globals;
    • binding_sites against CPython's symbol table for each construct the language reference lists as binding a name;
    • the five forms the review traced end to end now refuse the inventory, each against a control that reads.
  • Results at 08fdaaf1: 85 of the 126 inventory tests fail against the parent reader (round 5 found this holds only with the parent's enum_members call adapted; with only binding_sites shimmed, 45 fail). All 35 mutants of the reader's refusal clauses were caught (the set was not kept, so this could not be checked). The oracle fails when TPS is dropped from the inventory or the default is changed. The regenerated inventory is byte-identical, and the 196 SSI tests pass with the pinned interpreter. black and ruff are clean.

  • Correction: b8d9a68a's message gave "9 skipped (lane, seal, U2)". All 9 were SSI0 oracle tests, skipped where the pinned interpreter is absent.

  • The round-5 delta review (an Opus 5.5 reviewer, at 08fdaaf1) asked for revision, with three medium findings, each a module the reader read differently from Python and the pinned engine:

    • M1: a match class pattern's keyword, such as case object(__globals__=...), reached a function's globals, because the scan read only Name ids and attribute names;
    • M2: Variable was matched by spelling, so a local Variable with a metaclass, or a rebinding, could change what the engine reads. (Round 6 corrected this account: for the metaclass form, the pinned loader registers the local Variable class itself and fails loudly. Refusing the form is still right.);
    • M3: a PEP 263 coding cookie made the reader parse a different program from the one Python runs.
      Its low findings: a store through a member changed encoding indices unchecked; a value_type that was not a plain = Enum skipped the member check; two import clauses had no test that failed without them. Its notes: one test name overclaimed, and reflection through module attributes the model API exports is a boundary of the stated limit.
  • b682dcd2 fixes these:

    • the module scan reads every string field of every node outside literals;
    • the module may bind neither Enum nor Variable, and every attribute store refuses;
    • writing the fix found that Variable's constructor reads value_type, possible_values and default_value through self.set, which a body method or an assignment named set could override. The variable's body may now hold only a leading docstring, single assignments to the names that constructor reads, and formula functions without decorators;
    • every parse reads bytes, so a coding cookie is honoured;
    • value_type must be one plain assignment of a primitive type or Enum, or the inventory refuses (round 6 found this did not hold for a module that rebinds a primitive name; b1d0d029 closes it);
    • new head forms test the import clauses, and the method test now calls the reader;
    • the reflection boundary stays a limit, covered for the pinned release by the oracle (b1d0d029 states it in the script's header).
  • New oracle tests: invented modules load in the pinned engine with the members the reader reads, and a set override and a member store change what the engine gives; the constructor's attribute names equal the reader's allow-list; every pinned enum's indices are its member positions.

  • Results at b682dcd2:

    • 20 of the 150 inventory tests fail against 08fdaaf1's reader, with no shim;
    • the differential reads 745 of 2,000 examples over seeds 0 to 4 (133 to 164 per 400-example run);
    • 56 mutants of the reader's clauses are kept with the lane's build records. 53 are caught, and the 3 survivors are equivalent (round 6 corrected the reason given for one; see below);
    • the regenerated inventory is byte-identical;
    • with the pinned interpreter, 222 SSI tests pass (211 unit, 11 oracle);
    • black and ruff are clean.
  • The round-6 delta review (an Opus 5.5 reviewer, at b682dcd2) asked for revision, with one medium finding:

    • M1: value_type was read by the spelling of a primitive name, so a module that binds float = Enum gave the engine an Enum input that the inventory recorded as a float with no members.
      Its low findings: the single-target clause had no failing test, though a chained set binding beside an override changes the engine's members; four other clauses (deletes, keyword and parameter names, byte parsing of helper roots and core defaults) had none either; and the script's header did not state the reflection limit. Its notes: the S3 equivalence reason was imprecise, and this body overstated round 5's M2.
  • b1d0d029 fixes these:

    • a value_type, entity or period spelled by a name the module binds refuses the inventory, with tests for each primitive, an entity and a period (round 7 noted that the model-API alias test listed here is refused by the older known-name clause, not by this rule);
    • refused forms add a chained engine attribute, a chained set binding, a delete through a member and underscore keyword and parameter names; the engine oracle loads the chained set pair beside an admitted override;
    • two coding-cookie tests cover the helper roots and the core defaults, and a module that binds VALUE_TYPES twice refuses;
    • the header states that the static read does not follow reflection through objects the model API exports, and that only the pinned-engine oracle covers it;
    • a new oracle test compares each inventoried variable's value_type, default, entity and period with the pinned engine's.
  • The corrected S3 reason: a named model-API import binds a name to an object the model API exports, as its star import does, since the pinned model_api has no __all__. Binding Enum, Variable, the enum's name, a value_type's name or an entity's or period's name is refused either way (round 7 added the last), and an underscore name fails the scan.

  • Results at b1d0d029:

    • 7 of the 165 inventory tests fail against b682dcd2's reader;
    • 65 mutants of the reader's clauses: 62 are caught, and the 3 survivors are the known equivalents;
    • the regenerated inventory is byte-identical;
    • with the pinned interpreter, 238 SSI tests pass (226 unit, 12 oracle): contract 20, runner unit 41, dataset engine 3, engine 9, inventory 165;
    • black and ruff are clean.
  • 81a6db61 merges origin/master at 1ec57a5d (D1a, PSID income and wealth readers and field registry (D1a) #575). The birth-evidence check keeps D1a's exclusions and reachability assertion, then SSI0's; its 13 tests pass.

  • The round-7 delta review (an Opus 5.5 reviewer, at 81a6db61) asked for revision, with two medium findings that share one cause: the reader checked a variable's body and module only when its value_type was spelled Enum.

    • M1: a variable whose value_type is spelled as a primitive could still be an Enum input in the engine, through a set override, setattr, globals() or __builtins__;
    • M2: entity, period and a primitive default were read from the body's plain assignments, with no single-binding or store check, so an annotated or augmented rebinding, a tuple assignment, a module-level store, an item of the model API's entities list or a globals() store changed what the engine loads.
      Its low findings: the spelling and VALUE_TYPES tests exercised one binding form each; and the attribute oracle compared entities through a name conversion that is wrong for SPMUnit, and defaults (like validate_core_defaults) by == alone, so 1 passed for True. Its three notes correct earlier text: N1 and N2 are marked above, and N3 (under mutant D2 the core-defaults parse refuses as "not one plain table" rather than reading wrong defaults) is in the commit.
  • 04e12f58 fixes these:

    • every variable must be a plain class, as Enum variables already were: its name bound once, bases exactly Variable, no keywords or decorators, and a body of a leading docstring, single assignments to names Variable's constructor reads, and undecorated formulas, with each attribute the reader records bound at most once by plain assignment;
    • value_type, entity and period are each a name the module never binds, and a default is a literal of the variable's primitive type or a member of its enum class;
    • each variable module, and each module under policyengine_us/variables that it imports, with the package __init__ files the import runs, may import only the model API's star import and named imports from modules under policyengine_us.variables or policyengine_core, at top level; may define classes only at top level, on Variable or Enum; may store no attribute; and may name no reflective builtin, frame attribute or dunder name. Imported variables modules are followed in turn;
    • the spelling tests run over every binding form for float, Person and YEAR, and a second VALUE_TYPES binding by assignment, annotation, |=, match capture, import alias or parameter refuses, each against Python's answer;
    • the engine oracle reports entities and periods by their model-API names, read from policyengine_us.model_api, and compares defaults by type as well as value; validate_core_defaults compares by type too (round 8 found the oracle compared defaults by == and bool-ness only; a2b3952b makes it compare types);
    • the static-offset differential moves to test_ssi_static_offset.py, as the Tests section describes.
  • New tests: each route the review traced (and more), end to end against a control package, with Python's answer for each; a Hypothesis differential of the static read against Python over admitted forms of an invented module; literal defaults by type; each refused form of module code in a variable module, a module it imports and the package __init__ that import runs; string literals that spell reflective or dunder names, admitted in all three; a variable name bound again, and a variable class with type parameters; followed imports, package inits and import cycles; and an oracle test that loads every route in the pinned engine and shows each changes what the engine loads.

  • Results at 04e12f58:

    • 140 of the 380 inventory tests fail against 81a6db61's reader, in each of three Hypothesis seeds;
    • 103 mutants of the reader, in one run on the final files: 97 are caught, and the 6 survivors (S3, C4, C5, PV2, PV3, PV4) are equivalent, since an earlier check refuses every input that would tell them apart;
    • the regenerated inventory is byte-identical, with 2.18.0 as the comparison;
    • with the pinned interpreter, the 12 engine oracle tests pass (engine 9, dataset engine 3), and the run loads nothing from the estimates package;
    • black and ruff are clean.
  • 0f756216 merges origin/master at d8302233 (SM1, SM1: differential mortality by lifetime earnings, education and race (normalized within age-sex-year cells) #570) without conflicts: master adds SM1's modules to the birth-evidence reducer's exclusions and to the seal tests, beside SSI0's. At the merge, the SSI tests and the birth-evidence tests pass locally (465 passed, the 12 oracle tests on the pinned interpreter among them). The one failure is the seal reachability test, which needs modules this sparse clone leaves out; CI runs it.

  • 765c4879 recounts the tiers on that master.

  • The round-8 delta review (an Opus 5.5 reviewer, at 765c4879) asked for revision, with five medium findings. In each, the reader admitted a release while the pinned engine loaded a different default, value_type, entity or period, or refused to load:

    • M1: a module could change the engine's defaults at import time, through an admitted policyengine_core import and an item store or method call on its VALUE_TYPES table;
    • M2: a followed import was read from a different file than the one Python imports, when a package shadows a module of the same name or a package's __init__ has only bytecode;
    • M3: the reader's file index matched dot folders and __init__.py files, which the engine's directory walk skips, and kept the last of two files with the same stem;
    • M4: an int default of a float variable was recorded unconverted, though the engine converts it, so a large int read differently or failed to load;
    • M5: the engine's walk also runs modules outside the closure, and the header's list of limits left them out.
      Its low findings: four of its mutants (N1, N2, N6, N8) survived with no witness test, and "compares defaults by type as well as value" was false for the oracle. Its notes corrected wording in a docstring, the moved test, 04e12f58's message and this body.
  • a2b3952b fixes these:

    • code that runs at import in any module the reader reads is refused: calls, decorators, item stores and deletes, and in-place assignment (the last beyond the review, since |= changes the table with no call or store); the core imports are an allowlist, Simulation only;
    • each step of a followed import is resolved with PathFinder.find_spec, and anything but .py source loaded by SourceFileLoader refuses. Namespace steps are admitted, since they run no code and both pinned releases' followed paths use them;
    • the file index follows the engine walk's rules, and a dependency whose stem names two files refuses;
    • an int default of a float variable must convert exactly, OverflowError included;
    • the header states the walk's limit, in the sentence in the Invariants section;
    • the four mutants have witness tests, and the attribute oracle compares default types;
    • the docstring and the moved test's wording are corrected. 04e12f58's "Python's float default is shown for each" did not cover the import-alias case, which was not executed, and this body's "for every invented module the reader admits" holds over the Hypothesis domain.
  • New tests: the review's repros, each reaching the core table two ways; 15 import-time and 8 import forms refused, with 5 forms that stay admitted; shadow, sourceless, extension, submodule-name, cannot-resolve, case-mismatch and import-cache tests, checked against a fresh interpreter's find_spec where that applies (the extension, step-past-module and case-mismatch tests do not call it); the walk's file-index cases; exact and inexact int defaults, with a Hypothesis property; and two oracle tests: the core-table changes change what the pinned engine loads, and the file index equals the pinned engine's own walk.

  • Results at a2b3952b: the regenerated inventory is byte-identical; the SSI tests pass (contract 20, runner unit 41, inventory 486, and with the pinned interpreter engine 11 and dataset engine 3); the mutant and parent-check counts are in the Tests section; black and ruff are clean.

  • While writing the fix, the builder found that Python's source loader can run a module's cached bytecode instead of its source, which the reader never reads. Refusing any module with cached bytecode would refuse the installed releases, so 60b8ca24 states this limit in the reader's header, in the sentence in the Invariants section. The regenerated inventory is byte-identical.

  • 2864d622 merges origin/master at 0f69bbb2 (OP1, OP1: open-population harness around the sealed loop #566, and its report fix, Fix review r10's report findings for OP1 #589). Git auto-merged the birth-evidence reducer and its test, which both branches changed: the merge keeps master's OP1 lines and SSI0's exclusions and reachability block. tests/tier_counts.json and tests/README-tiers.md conflicted and now read master's counts plus SSI0's 562 tests. At the merge, the SSI tests pass as above, and the birth-evidence tests give 12 passed and 1 failed: the seal reachability test, which needs modules this sparse clone leaves out; CI runs it.

  • The round-9 delta review (at 2864d622) asked for revision, with one medium finding. M1: a module the closure imports could define a Variable class that overrides Variable.set. The reader checked such a class only for its bases, keywords and decorators, while the engine's walk builds it and runs the override; in the review's repro the engine gave employment_income a default of 7 where the reader recorded 0. Its low findings:

    • L1: the file index left out every __init__.py by name, while the engine leaves out only the path it joins for the folder's own init, so a folder name with a glob character class (invented_a[b]/) split them;
    • L2: three of its mutants (MY3, MY6, MY7) survived with no witness test, and MY2 survived in the safe direction;
    • L3: the attribute oracle derived the engine's type for an explicit float default without reading the record's type, so it compared the engine with itself;
    • L4: import resolution followed the reader's own environment, and PYTHONCASEOK without -I could make it read a different file from the one the engine imports.
      Its notes asked for an exact cached-bytecode sentence (N1), "where that applies" on this body's find_spec claim (N2), and an oracle test of its ten import-time forms without a call (N3).
  • 67e52e52 fixes these:

    • check_module refuses any module it reads, followed modules and package inits included, that defines a variable class with type parameters or a body plain_variable_body refuses; module_imports already refuses a class that is not a top-level statement, so a class inside a module-level if, try or with refuses there first;
    • variable_files leaves out only the match equal to os.path.join(directory, "__init__.py"), as the engine does, and refuses a folder whose path has a glob character;
    • the oracle derives the engine's default type from the record's own default and value_type, following the pinned Variable.set, and a new test that runs no engine compares each record's default and its origin with the pinned source;
    • the reader refuses when importlib._bootstrap_external._relax_case() holds, and the documented command passes -I; the header says resolution uses the reader's own path hooks and suffixes and asks no meta path finder;
    • the header's cached-bytecode sentence follows SourceLoader.get_code in CPython 3.13, and its oracle sentence says what is compared;
    • none of the new rules refuses anything in 2.2.1 or 2.18.0: in both, the followed modules are ssi_federal_living_arrangement.py (one plain variable class) and _apply_ssi_exclusions.py (no classes), no folder under variables/ has a glob character, and no file name ends in __init__.py without being one.
  • New tests: the review's repro end to end, with six kinds of variable class that is not plain in a followed module and in a package init, each against a plain control, and an oracle test in which the engine's walk gives 7 with the override and the recorded default without it; try and with class forms; the invented_a[b] layout and a package below a folder named invented[x], which refuse, and an SSI file named invented__init__.py, which stays a root; oracle tests for the engine's walk of invented_a[b]/, for invented__init__.py in the invented walk, and for variable_files against the pinned release's own walk, in order; witnesses for MY3 and MY7 as refused forms and as core-table changes, and an async helper as an admitted form, with each admitted form tested alone; the pinned-source default test; a child process with PYTHONCASEOK=1 and no -I on the review's case layout, which refuses; and an oracle test that loads each admitted form and each of the ten forms without a call, one at a time and together, as the reader records them. Like round 8's, the import tests are checked against a fresh interpreter's find_spec where that applies.

  • Results at 67e52e52: the regenerated inventory, run with -I, is byte-identical (sha256 93f6efbf…); the SSI tests pass (contract 20, runner unit 41, inventory 535, and with the pinned interpreter engine 16 and dataset engine 3); the mutant and parent-check counts are in the Tests section; black and ruff are clean.

  • ff70470a merges origin/master at a747bafa. Git flagged only tests/README-tiers.md and tests/tier_counts.json, which both branches changed; every other file master changed stands as master has it. The tier files carry the provisional counts in the Tests section.

  • The round-10 delta review (at ff70470a) asked for revision, with one medium finding. M1: in a module that binds Enum to Variable (by assignment, by import … as Enum, or by importing a plain variable class as Enum), a class on Enum was a variable class that no rule read, and the engine's walk ran its set override, which gave employment_income a default of 7. An SSI-tree class in that form went unrecorded. Its low findings:

    • L1: two of its mutants (Y1, Y3) survived with no witness test;
    • L2: this body left out the moved test's run at ff70470a.

    Its notes:

    • N1: the rewrite of engine_default_type catches no edit the old function missed;
    • N2: no bool equals 40;
    • N3: 67e52e52's message gave a stale count of round 8's mutants;
    • N4: the dataset-engine log recorded no byte hashes.
  • d06014b7 fixes these:

    • every module the reader reads may bind neither Enum nor Variable, in any form binding_sites reads (module_imports, through binds_model_api_spelling, which static_module shares). So a class on Enum is a core Enum and never a variable, and every variable class has a base spelled Variable. The header says the reader trusts the two spellings only because no module it reads binds them;
    • a sweep of every name the reader trusts by spelling (class bases, decorators, the values plain_variable and plain_variable_body admit, enum members, the model API's names and the engine attributes) lists each with the check that stops a rebinding, or the reason a rebinding cannot change a record (trusted-names.md in the round's evidence). Three had no check, and each now refuses:
      • an enum member named encode, which takes the class's encode method;
      • a formula name defined twice, of which the engine keeps the last while the record listed both;
      • an adds, subtracts or defined_for of a variable that is not a boundary, other than a string literal or a list or tuple of them. A name the module binds, a computed list, or an Enum member as defined_for hid from the record's dependencies the variables the engine loads in these attributes;
    • the engine-attributes oracle test also checks the reader's formula prefix against the pinned FORMULA_NAME_PREFIX;
    • the header states one gap the sweep found, as the first of the three limits above, and ef82f376 tests it for the pinned release;
    • the review's Y1 and Y3 now fail tests: trigger modules hold a class that is not plain before or after a plain one, in the tools and init positions, and the glob-folder test runs over [, ? and *;
    • this round's dataset-engine log records the bytes it ran, as every final log does (N4);
    • corrections to 67e52e52's message:
      • it says the oracle "now catches" edits that the old engine_default_type also caught. The test that resolves round 9's L3 is test_inventory_defaults_are_the_pinned_source_literals, which runs no engine (N1);
      • its "40, 40.0 and a bool of equal value" should say 40 and 40.0, since no bool equals 40 (N2);
      • its "round 8's 48 run against this commit" should say 103, since the sweep ran all 103 (N3).
  • New tests:

    • the review's four layouts (followed_assign, closure_assign, closure_import_alias, closure_intermediate) end to end, each against Python's answer, with controls without the binding;
    • the SSI-tree layout;
    • every binding form of Enum and of Variable in a variable module, each against a control that binds another name;
    • Enum = Variable among the refused module forms in a variable module, a followed module and a package init;
    • the encode member, the formula defined twice, nine attribute forms that name variables outside a literal, five literal controls and a boundary with computed adds;
    • three oracle tests:
      • the engine's walk of followed_assign gives employment_income 7 while the reader refuses;
      • the engine's own Enum loads a member named encode in order and loses its encode method;
      • the engine loads each refused adds, subtracts and defined_for naming variables the record would not list, and holds only the last of two formulas of one name.
  • Results at d06014b7:

    • the regenerated inventory, run with -I, is byte-identical (sha256 93f6efbf…). None of the 87 modules the reader reads in either release binds Enum, Variable, encode, a primitive type, or an entity or period the records name. (Formula parameters and locals bind person, parameters, tax_unit and marital_unit, and four modules import _apply_ssi_exclusions under its own name. The read uses these names only to add dependencies. d06014b7's message says "or another spelling the reader trusts", which is too broad for these.);
    • contract 20, runner unit 41 and inventory 627 pass;
    • the mutant and parent-check counts are in the Tests section;
    • black and ruff are clean.
  • ef82f376 adds test_engine_trace_reads_only_what_the_inventory_lists, which the session that ran this round wrote after the build. The pinned engine runs with its full tracer over nine invented households, and the test checks the trace against the record, as the Invariants section says. Four controls show that each kind of gap fails it: a record removed, a dependency removed, an invented record no household reads, and the parameters removed. Over the nine households the engine read 93 variables and 76 parameters, of which only the seven route names and the gov.abolitions. gates sit outside the record, and two self-edges (ssi, ssi_countable_income) sit outside its dependencies. The header's first limit now says what the test covers and what stays outside it; the reader's code otherwise stands, by ast.dump, as d06014b7 left it. The commit's message corrects two statements in d06014b7's: "another spelling the reader trusts", and its count of the engine tests that finished.

  • 691111f0 carries the provisional tier recount in the Tests section.

  • Results at 691111f0: contract 20, runner unit 41, inventory 627, engine 20 and dataset engine 3 pass; the regenerated inventory is byte-identical; the moved test passes in its throwaway clone.

  • The round-11 delta review (an Opus 5.5 reviewer, at 691111f0) approved it, with no high or medium finding. None of its findings changes a record in 2.2.1 or 2.18.0. Its low findings:

    • L1: the trace test calculated every listed variable, so its check that the engine reads every listed name could never fail;
    • L2: the header's list of what the trace test leaves out missed the reform the runner always passes. Under a reform labor_supply_behavioral_response reads 13 elasticity parameters before it gives 0, and the dataset route's simulation also sits outside the test;
    • L3: a string literal could hide a dependency. The reader kept a name that adds, subtracts or defined_for gave only if a file's stem matched it, and it expanded a string only under gov., so a class in a file of another stem or in an underscore file read as an input. trusted-names.md listed neither check.

    Its notes:

    • N1: the gate prefix's comment said a trace holds one gate for each variable; the engine reads one only for a variable that has one;
    • N2: this body's first limit said dependencies come only from string literals. They also come from the values of a parameter that adds or subtracts names, and of the literals only those equal to a file's stem, or an accessor call's first argument, count;
    • N3: a boundary's dependencies are skipped, so a literal defined_for on a boundary would mask its input unseen;
    • N4: Y5 hit the reviewer's timeout, and Y7 now fails only through its error message.
  • 4150b7d4 fixes these:

    • the trace test calculates only the 52 federal SSI variables, and the nine households still read every listed name, so the check can fail (L1);
    • it also traces each household under the reform of all seven overrides the runner admits, allows the elasticity parameters only there, and asserts that the response stays 0 and that no admitted override sits under them. The header and the comments say so, and name the dataset route's simulation as outside the test (L2, N1);
    • every name that adds, subtracts or defined_for gives stays a dependency whatever file defines it, so a name the file index misses refuses as unresolved. A string names a parameter wherever it sits, one that names no parameter refuses, and a list item with a period names a parameter, as the engine reads them (L3);
    • the header states where a record's dependencies come from and names a boundary's literal defined_for as unread (N2, N3);
    • N4 needs no change: Y5 can only refuse more, as the Tests section says. trusted-names.md gains the two rows in this round's evidence.
  • New tests: 16 in test_ssi_inventory.py. A name the stem index misses refuses in eight layouts; a string names a parameter under gov. and elsewhere; one that names no parameter refuses; a list item with a period names a parameter; defined_for keeps a dependency of any stem the index finds; and a name equal to its own variable stays no dependency.

  • f92719ce carries the provisional tier recount in the Tests section.

  • Results at f92719ce:

    • regeneration, run with -I, gives the same inventory.json bytes (sha256 93f6efbf…), and neither release refuses;
    • contract 20, runner unit 41, inventory 643, engine 20 and dataset engine 3 pass;
    • the moved test passes in its throwaway clone (1 passed);
    • the mutant counts are in the Tests section;
    • black and ruff are clean.
  • The round-12 delta review (at f92719ce) asked for revision, with three medium findings. Each broke a claim the PR states for every input, in forms only invented modules reach; no record of either release changes under the fix.

    • M1: the reader read a variable with no formula as derived when it had any dependency. So a defined_for or a label equal to a file's stem made an engine input derived, and its default reached the calculation unrecorded, while an adds of parameters only, or of a parameter that lists nothing, made an engine aggregate an input.
    • M2: a body literal counted as a dependency when it named a class the walk had already read, and the walk followed string hashing, so the documented -I command could give two inventories for one source.
    • M3: dotted names resolved through the file system, which drops empty parts and here ignores case, not through the engine's parameter tree. A name equal to its own variable dropped out, and a list item with a period, or a formula's prefix, that named nothing passed.

    Its low findings:

    • L1: the trace test cannot see a parameter read through adds or subtracts;
    • L2: the reform assertions pass for an empty reform;
    • L3: the header named only the dataset route as outside the trace test, and nothing backed "as the runner always passes";
    • L4: four routes (B3, B7, B10, B19) had no test;
    • L5: nothing pinned the trace targets to the 52 roots.

    Its notes: N1, a file with no values raised KeyError; N2, the safe-direction refusals needed a sentence; N3 and N6, the first limit was inexact; N4, the birth-evidence log's expected failure; N5, when unread can fail on a correct record.

  • cba389ab fixes these:

    • the reader decides inputs by the engine's rule (M1). An input's dependencies are still followed, so a defined_for gate resolves, and an oracle child compares each pinned record's input status with is_input_variable();
    • a body literal counts by the source alone. The walk pushes dependencies in sorted order and reads a dependency's file even when a class of that name was already read, and a variable name read from two files refuses (M2). The search for other order-dependent output found that last case: the record took whichever file the walk read last;
    • dotted names resolve as get_parameter does, by exact os.listdir names, to a .yaml file of dated values, with a ValueError for anything else (M3, N1). A naming attribute that names its own variable refuses, a formula's lagged read of its own variable stays no dependency, and a formula prefix that names nothing refuses; in both releases all 38 record–prefix pairs, over 22 distinct prefixes in each release, name a .yaml file;
    • the header and the trace test say the tracer records only a formula's reads, and the attribute oracle compares adds, subtracts and defined_for with the engine's (L1);
    • the trace child returns the individual FBR from each simulation's tree, and the test asserts the reform's 1000 there (L2);
    • the header lists the four differences between the trace test and calculate_household. compile_reform({}) returns None, so the runner passes a reform whenever a case has an override, not always (L3);
    • tests kill B3, B7, B10 and B19 (L4), and the trace test asserts that its targets number federal_ssi_variable_count (L5);
    • the header lists the safe-direction refusals (N2) and states the first limit exactly (N3, N6), and a comment at unread says when it can fail on a correct record (N5).
    • A sweep compared every rule the header and this section state for every input with the engine's code (claim-sweep.md in the round's evidence). Five rules differed in forms the engine refuses to load, and the reader now refuses each: two computation modes in one variable; a defined_for that names an Enum or str variable; a variable name in two files; a parameter file that repeats a key; and a .yml file in the SSI parameter tree. The engine also refuses a variable with no label, which the reader does not check: the header states that limit. trusted-names.md gains four rows: the dotted-name mapping, the self-name, set(records), and dependency emptiness as the input rule.
  • New tests:

    • in test_ssi_inventory.py, a net 80 (81 added, the inverted test removed): the body-literal test, the input rule's 8 forms and an input's followed dependencies; 10 defined_for gates; 30 refused and 6 admitted naming forms; the self-names and a lagged self-read; 5 formula prefixes; repeated keys and a .yml file; 4 mixed and 3 single computation modes, one in a followed module; a name in two files; and three layouts read under four hash seeds in child processes;
    • in test_ssi_inventory.py, 6 more from cb728630, for the four mutants that survived at cba389ab: a class read from a stem file after another file, a formula prefix at a .yml file, a boundary's literal adds that names itself or an absent parameter, and a parameter file that holds a list or nothing;
    • in test_ssi_engine.py, 4 that build no country system: the core harness for the input rule, for the naming forms and for the load-time refusals, and a static check of the core constants the reader mirrors. The attribute oracle and the trace test gain the assertions above.
  • Results at cb728630:

    • regeneration, run with -I, gives the same inventory.json bytes (sha256 93f6efbf…), and every record of 2.2.1 and of 2.18.0 equals the record f92719ce's reader gives;
    • contract 20, runner unit 41, inventory 729, engine 24 and dataset engine 3 pass;
    • the moved test passes in its throwaway clone at 208b4d49 (1 passed);
    • the mutant counts are in the Tests section;
    • black and ruff are clean.
  • The round-13 delta review (an Opus 5.5 reviewer, at 208b4d49) approved, with no high or medium finding. Both pinned releases keep byte-identical records, all 37 of round 14's mutants fail, and it found three low findings and seven notes. Invented modules reach each of them, and round 15 found that pinned lists also reach one, the future-only list below.

  • A review's exit rule now applies. A finding that only invented inputs reach, with zero effect on pinned inputs, stays as a stated limit, and the next PR that moves the pinned release must recheck each limit below. A regression, a falsified claim, a changed record on a pinned input, or a misread real rule still gets a fix or a narrowed claim.

  • 146c3723 narrows the claims round 13 falsified, in text only: both files' syntax trees match 208b4d49's, docstrings aside. This body narrows the same claims.

    • Commit messages stay as pushed, and two sentences of cba389ab's need this correction. The core harness shows the engine reading most of the header's safe-direction forms, and it raises on string_folder and string_node_file as the test spells them. The table holds five load errors, where the message says three more.
  • Stated limits, one line for each form:

    • A nested .yml: the reader's rglob refuses a .yml file below a subfolder of the SSI parameter tree, and no test covers that depth (mutant V3 survives).
    • index.yml, reference.yml or __pycache__.yml in that tree: the reader refuses, though the engine loads none of them as a parameter.
    • adds = None or subtracts = None: the reader refuses, and the engine treats the variable as an input.
    • A bracket part (scale[0]) or a baseline. name: the reader refuses, and the engine reads it.
    • A self-name on a later date only: the reader refuses, and the engine reads the variable at an earlier period.
    • A folder named index, reference or __pycache__: the reader resolves it as the engine does, and nothing pins that (mutant V2 survives).
    • Empty adds or subtracts, a formula dated past the period, or a formula past its end: the record marks the variable derived, as is_input_variable does, and the engine gives the default with nothing supplied.
    • A string adds whose parameter starts after the period: the reader admits it, and the engine raises TypeError at that period. Pinned lists have this form: in both releases earned.yaml, unearned.yaml and countable.yaml start on 1975-01-01, and prepare accepts 1974. The pinned route refuses every year before 2022 first, as the round-16 entry below shows, so no pinned case reaches that error.
    • A reader regression reaches the attribute oracle and the trace test only after a regeneration, since both read the committed inventory.json.
  • Master 6413d842 merged with conflicts only in tests/README-tiers.md and tests/tier_counts.json, which take master's blobs and then this PR's recount: unit 20,294, artifact 4,271, integration_psid 1,471, reproduction_legacy 520, oracle_policyengine 336, 26,892 in all.

  • Master 18082859 (S0.1: source, exposure, access and power audit for SM2–SM4 and ED1–ED2 #588) merged the same way: 7659cd08 takes master's two tier files, and 56bbcde8 recounts them to unit 20,454, artifact 4,271, integration_psid 1,471, reproduction_legacy 520, oracle_policyengine 336, 27,052 in all.

  • Results at ace1f1c5. They stand at 56bbcde8, since git diff --name-only ace1f1c5 56bbcde8 names only S0.1: source, exposure, access and power audit for SM2–SM4 and ED1–ED2 #588's own files and the two tier files, none of which these runs read:

    • regeneration, run with -I, gives the same inventory.json bytes (sha256 93f6efbf…);
    • contract 20, runner unit 41, inventory 729, engine 24 and dataset engine 3 pass;
    • the moved test passes in its throwaway clone at ace1f1c5 (1 passed);
    • both changed files' syntax trees still match 208b4d49's, docstrings aside.
  • The round-15 delta review (GPT-6.1 Sol, at 56bbcde8) asked for revision, with two medium findings, both falsified claims. Neither is a regression, and regeneration gave the same records.

    • M1: the .yml sentences left out the file stem __pycache__, which the pinned core also skips.
    • M2: this body called the future-only list an invented form. In both releases the three income lists start on 1975-01-01, ssi_earned_income uses the earned list and prepare accepts 1974. A core harness over those bytes raises TypeError for 1974 and returns a value for 1975.
  • c865dce1 answers both and changes no runtime path:

    • the reader's docstring and this body name all three stems;
    • invented cases through the real runner show the pinned route stops before those lists matter. Every year from 1972 to 2021, plus 1000 and 1900, ends in a counted RULES_ENGINE_GAP from the worker, and 2022 gives the first result. The worker's error reads ParameterNotFoundError to 2016 and SPMInputError from 2017 to 2021;
    • the runner's docstring now says such a year refuses from the worker, and test_years_before_2022_end_in_a_counted_refusal holds seven of those years and 2022;
    • 2.18.0 gets no run, since check_versions refuses any release but the pin, so the next PR that moves the pin must recheck this limit.
  • Results at c865dce1:

    • regeneration, run with -I, gives the same inventory.json bytes (sha256 93f6efbf…);
    • contract 20, runner unit 41, inventory 729, engine 25 and dataset engine 3 pass;
    • the moved test passes in its throwaway clone at c865dce1 (1 passed);
    • the reader's and the runner's syntax trees match 56bbcde8's, docstrings aside.
  • The round-16 delta review (GPT-6.1 Sol, at c865dce1) approved, with no finding:

    • M1 holds: the pinned core skips index, reference and __pycache__, and the reader's docstring and this body name all three;
    • M2 takes the narrowed claim. The review scanned 24 parameters in each release, and every one has values by 2022;
    • its own regeneration against 2.2.1 and 2.18.0 gives the same inventory.json bytes, and its separate runs pass contract 20, runner unit 41 and inventory 729;
    • its tier counts, black and ruff match this body.
  • The review's own probes through the real runner timed out on its lane, so it asked for one more run on the host. At c865dce1 (2026-11-02, 14:39Z), its probe with no policy overrides ran two invented cases. 1974 ends in a counted RULES_ENGINE_GAP (ParameterNotFoundError), and 2022 gives a result: 2 attempted, 1 accepted, 1 refused, denominator 2. The checkout stayed clean.

  • Upstream, after the approval: SSI: retirement funds never count as resources, but POMS SI 01120.210 counts an owner's accessible lump sum policyengine-us#10446 files the retirement-fund gap, and its RuleSpec mirror is Encode SSI retirement-fund resources under POMS SI 01120.210 (PE-US #10446 parity) TheAxiomFoundation/rulespec-us#1910. Comments on SSI: deemed benefit is capped at the individual rate instead of the no-deeming amount, and couples are identified by tax roles policyengine-us#10138 and Encode the SSI spousal-deeming benefit limit (20 CFR 416.1163(d)-(f)) and SSI couple definitions (416.1801(c), 416.1806, 416.1160(d)) (PE-US #10138 parity) TheAxiomFoundation/rulespec-us#1706 confirm that the spousal-deeming cap gap is still on PE-US main and add two boundary cases.

axiom: n/a: microsim-side interface, inventory and contract over the certified PolicyEngine release; no country-model or RuleSpec encoding changed (the retirement-fund gap goes upstream as a separate issue)

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits October 24, 2026 10:54
Plain-request captures of the SSI legal sources, the certified
PolicyEngine release metadata and the PyPI records of every installed
distribution, each with URL, retrieval time, size and SHA-256 in its
manifest. A folder-level .gitattributes stores the bytes as fetched.

Built by a Subfleet build lane in a standalone clone; committed by the
coordinating session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The static inventory of federal SSI variables, parameters and inputs in
the certified PolicyEngine release, and contract ssi0-v1 mapping each of
its 41 engine inputs and 12 context rows to PSID, SIPP and Microcosm
sources. Both are reproduced by the scripts added here; unmapped inputs
refuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Typed records, input validation, the runner that admits or refuses each
case with counted accounting, and a separate-interpreter worker that
calls only the public PolicyEngine interfaces of the pinned release.
Unit tests use invented records; the oracle tests run only when
POPULACE_DYNAMICS_PE_US_PYTHON_SSI0 names the pinned interpreter.

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

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
social-security-model Ready Ready Preview Nov 1, 2026 9:06pm UTC

Request Review

The pin hashed each primary distribution's whole RECORD, whose
console-script entries carry the interpreter's own path in their
shebangs, so the same release installed anywhere but the build's
temporary path was refused. Hash only the entries inside site-packages,
in both the child check and the pin script, and record the new digests
(identical for the build's interpreter and ~/.venvs/policyengine-py-6.10.2).
Two properties: the digest ignores entries outside site-packages and
changes with any package entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits October 24, 2026 16:54
black and ruff read every .py file in the repository, so the pinned
copy of policyengine-us 2.2.1's ssi_if_takes_up.py failed the lint job.
Rename the capture to .py.txt and update the two capture manifests and
the captured-sources table. Its bytes, size and SHA-256 are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SSI interface is opt-in, and nothing in the historical projection
imports it. List its twelve source files, the package data included, as
post-review exclusions in the birth-evidence script and its expected
tuple, and assert that none of its modules is reachable from the
birth-evidence reducer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pooled worker calculation that failed copied its error to every request
in the pool. So one invalid case refused every valid case pooled with it
(review round 2). The worker now reruns each case alone after a pooled
failure, through the same path a batch of three or fewer uses, and only a
case that fails alone reports an error.

The inventory now reads each enum variable's member names from the pinned
source, and the contract row for immigration_status carries them. The
contract admits an enum input only when it names a member. An invalid name
therefore refuses its own case as INPUT_CONTRACT_GAP before any calculation
instead of reaching the engine and counting as RULES_ENGINE_GAP.

Invariants, each with a property test on invented data:
- a case's outcome does not depend on which other cases share its batch;
- an enum input is admitted exactly when it names a pinned member;
- an enum input whose members cannot be read refuses the inventory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 3 approved 48a7198 with one low finding: that commit's
message said every listed invariant had a property test, but the
inventory's refusal of an enum input with unreadable members had only one
fixed example. Two Hypothesis properties now cover the extraction:

- generated member lists round-trip from an invented enum class;
- an enum input whose possible_values names an absent class, an empty
  enum or a class that is not an Enum always refuses the inventory.

Each fails when the extraction lowercases its names or the refusal is
removed. Test-only; no source or generated file changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The inventory read an enum input's members from every plain assignment
in a same-named Enum class. Three gaps let it disagree with Python:

- annotated, tuple, private and _sunder_ targets, non-literal values
  and nested classes were dropped or admitted without regard to
  Enum's own rules;
- the first class definition won, whatever else the module bound to
  that name;
- the default was never checked against the members.

None affects the pinned release: its three enum classes use plain
string assignments, their defaults are members, and the regenerated
inventory, contract and decision table are byte-identical.

enum_members now returns None, so the inventory refuses the input,
unless the module binds the name once, the class subclasses Enum alone
with no decorators or keywords, and its body holds only a leading
docstring, pass, methods and assignments of a string or integer
literal, or an earlier member, to public names, each named once. An
enum whose default names another class or no member stays unresolved.

Invariants and tests:
- Whatever the reader admits, Python's Enum defines identically (a
  Hypothesis differential over invented class bodies against
  enum.Enum). With the old reader it finds
  `INVENTED_A: str = "invented_a"` read as no members, and
  `_INVENTED_A = 0` admitted.
- The admitted forms with at least one member are always read.
- Refused forms, second bindings, other bases, decorators, keywords
  and the name mro are never read.
- A default outside its own class's members refuses the inventory.
- Oracle: each committed enum record, in both the input and variable
  lists, matches its class executed from the pinned source under the
  pinned release's own Enum, and the source hash matches. Dropping one
  member from either list fails it.

Tests: 100 passed and 9 skipped (lane, seal, U2); the 9 oracle tests
pass on the pinned interpreter. Unit 83 (12 new), oracle 9 (1 new).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The round-4 review found that the reader's claim, that Python's Enum
defines whatever it admits the same way, failed for plain static forms:

- methods were skipped as non-members, but a decorator can make one a
  member and an __init__ hook can drop members;
- the binding count read only top-level statements, so a class in an
  if block, a walrus, a match capture, a global declaration in a
  function or class, a guarded or aliased import, or a star import
  after the class rebound the name unseen;
- the variable's own body was never checked, so a second binding of
  possible_values, or a rebinding of the class inside the body,
  changed the class the engine sees;
- an alias passed into the contract, although the engine's
  Enum.encode looks names up by iterating the class, which yields
  canonical names only;
- Enum was matched by spelling, so a module-local Enum could change
  membership.

Writing the fix turned up a further gap: module code could reach the
variable itself, through an attribute store such as
invented_status.possible_values = Other, a decorator, or a rebinding
of the variable's name.

None of these affects the pinned release. Its three enum modules
import only the model API, their classes hold plain string
assignments, and the regenerated inventory is byte-identical.

The reader now:
- counts every binding site of a name in any scope: assignments of
  each kind, imports, definitions, parameters, except and match
  captures, type parameters, del, global and nonlocal declarations,
  and attribute stores. The class must be the only one, a top-level
  class defined before its variable;
- requires the variable to be its name's only binding, to subclass
  Variable alone with no decorators or keywords, and to bind
  value_type, possible_values and default_value once each by plain
  assignment, with no attribute store to those names in the module;
- refuses a module that imports anything but the model API's star
  import before the class, binds Enum, names exec, eval, compile,
  globals, locals, vars, getattr, setattr, delattr or a frame's
  f_globals, f_locals or f_builtins, or names anything with a leading
  underscore, such as a function's __globals__;
- allows the class to be read outside its body only as
  possible_values, the default, a member or encode;
- refuses methods, aliases, equal values and chained targets in the
  class body.

Reflection past these names, and code in other modules, is beyond a
read of one module. The oracle now loads the engine's country model
and reads each enum variable's class from it, so such code in the
pinned release would show there.

Invariants and tests:
- Whatever the reader admits, Python gives the variable the same
  members, with no aliases, and the same default. A Hypothesis
  differential runs 400 invented modules against Python, each with at
  most one refused form among admitted ones. Of 2,000 drawn examples,
  819 are read and compared.
- Each refused form is refused on its own. For each one marked
  observable, Python's answer also changes, so the refusal matters.
  These include (lambda: None).__globals__[...] and a generator
  frame's f_globals.
- binding_sites agrees with CPython's symbol table on each construct
  that the language reference lists as binding a name, with global
  declarations, at module level and nested in a function and a class,
  and on eight forms that only read the name. Attribute stores count
  although the symbol table does not track them.
- The five forms that put one member list in the input record while
  the variable held another now refuse the inventory end to end, each
  against a control that reads.
- The oracle checks each loaded class's source path and hash, its
  base (policyengine_core's Enum), its members against its canonical
  names, and the default. Dropping TPS from the inventory, or
  changing the default, fails it.

The unreadable-members test now passes a member of the intended class
as the default, so each defect alone causes the refusal. An empty
class has no member to name, so either check refuses it.

Correction: b8d9a68's message gave "9 skipped (lane, seal, U2)". All
9 were SSI0 oracle tests, skipped where the pinned interpreter is
absent.

Verification: the 196 SSI tests (187 unit, 9 oracle) pass with the
pinned interpreter. 85 of the 126 inventory tests fail against the
parent reader, with its top-level count standing in for
binding_sites, among them the differential and all five end-to-end
cases. All 35 mutants of the reader's refusal clauses are caught.
Regenerating against the pinned release, compared with 2.18.0, gives
a byte-identical inventory. black and ruff pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
M1, identifiers outside Name and Attribute. static_module scanned only
Name ids and attribute names, so a match class pattern's keyword, such
as case object(__globals__=...), reached a function's globals unseen.
It now scans every string field of every node outside literals: pattern
keywords, def and class names and keyword argument names. A literal
such as label = "_invented exec" stays admitted.

M2, Variable by spelling. The module may now bind neither Enum nor
Variable. Writing the fix found more routes to what the engine reads:
policyengine_core's Variable constructor calls self.set to read
value_type, possible_values and default_value, so a body method or an
assignment named set could override it, and an override can remove its
own name before the engine checks for unknown attributes. The
variable's body may now hold only a leading docstring, single
assignments to the names that constructor reads (ENGINE_ATTRIBUTES),
and formula functions without decorators. Every attribute store in the
module refuses, including stores through Variable, a member or an
alias.

M3, coding cookies. Every parse reads bytes, so source is decoded as
Python decodes it, PEP 263 cookie included.

L1. A store through a member, such as Enum.MEMBER.index = 0, refuses,
and the oracle checks that every pinned enum's indices equal its member
positions.
L2. value_type must be one plain assignment of a primitive type or
Enum, with no attribute store, or the inventory refuses ("Unresolved
value_type").
L3. Head forms for a star import from another module and a relative
model API import now fail without the import clauses.
N1. The method test is renamed and now calls the reader.
N2 stays a stated limit: reflection through module attributes the model
API exports is not read statically. The oracle, which loads the pinned
engine, covers the pinned release.

New oracle tests, on the pinned interpreter:
- invented modules load in the pinned engine with the members the
  reader reads, for each admitted form and for all of them together.
  A set override and a member store load without error but change what
  the engine gives, which is why the reader refuses them;
- ENGINE_ATTRIBUTES equals the names the pinned constructor reads,
  through set or by popping them.

Invariants:
- The inventory reads an enum input's members only from a module whose
  own code cannot change them; whatever it reads, Python and the pinned
  engine give the same members, with no aliases, and the same default.
- Each variable's value_type is one plain primitive or Enum assignment,
  or the inventory refuses.
- Source is decoded as Python decodes it.
- ENGINE_ATTRIBUTES equals the attributes the pinned Variable reads.
- Each pinned enum's indices are its member positions.

Corrections to 08fdaaf's message:
- "names anything with a leading underscore" was false for names held
  outside Name and Attribute nodes (M1). It holds now.
- "subclasses Variable alone" matched Variable by spelling (M2). The
  module may no longer bind it.
- "85 of the 126 inventory tests fail against the parent reader" held
  only with the parent's enum_members call adapted. With only
  binding_sites shimmed, 45 failed.
- "Of 2,000 drawn examples, 819 are read" is not reproducible, because
  Hypothesis draws differ between runs. The review got 746 to 769.
- "All 35 mutants are caught" could not be checked, because the set was
  not kept.

Results at this commit:
- 20 of the 150 inventory tests fail against 08fdaaf's reader, with no
  shim.
- The differential reads 745 of 2,000 examples over seeds 0 to 4, from
  133 to 164 per 400-example run.
- 56 mutants of the reader's clauses, now kept with the lane's build
  records: 53 are caught. The 3 survivors are equivalent: a named model
  API import must bind Enum, Variable or the enum's name, which the
  binding checks refuse; an empty class fails the default-member check;
  a leading-underscore member name fails the identifier scan.
- The regenerated inventory is byte-identical with inventory.json.
- With the pinned interpreter, 222 SSI tests pass: contract 20, runner
  41, inventory 150, engine oracle 8 and dataset oracle 3. By tier,
  unit 211 and oracle_policyengine 11.
- black and ruff are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
M1, value_type by spelling. parse_variables matched a primitive
value_type by its name, so a module that rebinds the name, as
float = Enum does, gave the engine an Enum input that the inventory
recorded as a float with no members. The inventory now refuses a
value_type whose name the module binds anywhere ("Unresolved
value_type"), and the same rule covers the names an entity and a
definition period are spelled by ("Unresolved entity", "Unresolved
definition_period"). Tests add a rebinding of each primitive type, an
entity and a period bound in the module, and a value_type spelled by a
name the module never binds, such as one a star import of the model API
could bind to Enum. A new oracle test checks each inventoried variable's
value_type, default, entity and period against what the pinned engine
gives it.

L1, the single-target clause. A refused form chains an engine attribute
with another name (label = invented_note = "note"), and another binds
set beside a reference (reference = set = invented_set) after an
admitted helper that overrides set. The engine oracle now loads that
pair, which changes the members the engine gives without an error.

L2, clauses without a failing test. Refused forms add a delete through a
member (del InventedEnum.MEMBER.index), an underscore keyword argument
name and an underscore parameter name. Two tests put the SSI helper
roots and the core primitive defaults under a utf-7 coding cookie, so a
parse that reads text instead of bytes misses a helper's dependency or
reads the wrong defaults. validate_core_defaults now also refuses a
module that binds VALUE_TYPES twice, since Python keeps the last.

L3, the reflection limit. The script's header now says the static read
does not follow reflection through objects that the model API exports,
and that only the pinned-engine oracle tests cover that, for the pinned
release: they compare each inventoried variable's value_type, default,
entity and period, and each enum input's members, with what the engine
loads.

Corrections:
- b682dcd's L2 line and its value_type invariant were false for a
  module that rebinds a primitive name (M1). They hold now.
- b682dcd gave the three surviving mutants' S3 reason as "a named model
  API import must bind Enum, Variable or the enum's name". It need not:
  a named import of YEAR binds none. The mutant is equivalent because a
  named model-API import binds a name to an object the model API exports,
  as its star import does, since the pinned model_api has no __all__.
  Binding Enum, Variable, the enum's name or a value_type's name is
  refused either way, and an underscore name fails the scan.
- The PR body said round 5's M2 forms changed what the engine reads. For
  class Variable(Variable, metaclass=...), the pinned loader registers
  the local Variable class itself and fails loudly. Refusing the form is
  still right.

Invariants:
- Each variable's value_type is one plain assignment of a primitive type
  or Enum, by a name its module never binds, or the inventory refuses.
- The entity and period are spelled by names the module never binds.
- The core defaults come from one plain VALUE_TYPES table.
- For the pinned release, each inventoried variable's value_type,
  default, entity and period equal what the engine gives.

Results at this commit:
- 7 of the 165 inventory tests fail against b682dcd's reader.
- 65 mutants of the reader's clauses, kept with the lane's build records:
  62 are caught. The 3 survivors are the known equivalents (S3 above; an
  empty class fails the default-member check; a leading-underscore
  member name fails the identifier scan).
- The regenerated inventory is byte-identical with inventory.json.
- With the pinned interpreter, 238 SSI tests pass: contract 20, runner
  unit 41, dataset engine 3, engine 9, inventory 165. Tiers: unit 226,
  oracle_policyengine 12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	scripts/first_estimates_birth_evidence.py
#	tests/estimates/test_birth_evidence_artifact.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits November 1, 2026 05:12
M1 needed the reader to decide inputs by the engine's rule. The reader now
records which naming attributes each class binds, and reads a variable that
is not a boundary as an input exactly when it has no formula and sets
neither adds nor subtracts, as is_input_variable does; a defined_for or a
label plays no part. The inventory still follows an input's dependencies,
so a defined_for gate resolves and has a record. Reader tests cover the
review's three forms, the label route and four more. The attribute oracle
child, which already builds the country system, now compares each pinned
record's input status with is_input_variable, and a new core-harness
oracle, which builds none, does so for every invented form.

M2 needed a body literal to count by its source alone. The reader drops
set(records) from the names a literal may match. It also pushes
dependencies in sorted order, reads a dependency's file even when a class
of that name was already read, and refuses a variable name read from two
files, as the engine does: a search for other order-dependent output found
that the record took whichever file the walk read last. A new test reads
three invented layouts, the review's among them, under four hash seeds in
child processes and in process, and gets one output for each. A probe in
the round's evidence finds that f92719c's reader gives two or more outputs
for each layout over seeds 0 to 7.

M3 needed dotted names to resolve as get_parameter resolves them. The new
parameter_child walks exact os.listdir names from parameters/, so case
counts on this volume, and refuses an empty part, an absent name, a name two
entries give and a key inside a YAML node. parameter_file admits only a
.yaml file that the engine builds as a dated Parameter, and raises a
ValueError otherwise, never a KeyError (N1). Every string adds or subtracts
and every list item with a period goes through it. A naming attribute that
names its own variable, directly or through a parameter's list, now
refuses, and the self-name test is inverted; a formula's lagged read of its
own variable stays no dependency. A formula's parameter prefix that names
neither a file nor a folder now refuses: in both releases all 38 prefixes
name a file, so no record changes. Reader tests cover 30 refused and 6
admitted naming forms, the review's six among them. The core-harness
oracle shows the engine raising on the review's five raising forms and on
the self-names, refusing to load three more, and reading the key inside a
YAML node and every form the header lists as a safe-direction refusal.

L1 needed the claim that every parameter the engine reads is on the record
narrowed: the tracer records only a formula's reads. The header and the
trace test say so, and the attribute oracle compares each pinned record
with the adds, subtracts and defined_for the engine holds, and with the
names a string's parameter lists on any date.

L2 needed the reform to show that it took. TRACE_CHILD returns the
individual FBR from each simulation's tree, and the trace test asserts that
the reformed value is INVENTED_POLICY's 1000 and that the plain one differs,
which an empty reform fails.

L3 needed the header to name what the trace test leaves out. It now lists
the four differences from calculate_household. compile_reform passes no
reform for a case without overrides, so the comment that the runner always
passes one now says it passes one whenever a case has an override.

L4 needed tests for four routes. list_item_outside_gov kills B3,
defined_for_names_a_parameter kills B7, string_lists_a_class_of_another_stem
kills B10, and gate_of_another_stem_beside_adds and gate_beside_adds kill
B19.

L5 needed the trace targets pinned to the roots. The trace test asserts
that the target count equals federal_ssi_variable_count, which removing the
root filter fails.

N2's safe-direction refusals are listed in the header's first limit, with
a built parameter such as gov.abolitions.<name>. N3 and N6: the first limit
now names list items with a period as parameters, the self-name refusal,
the union of a parameter's lists over all dates, and literals that equal a
class of the same module. N5: a comment at unread says when it can fail on
a correct record.

The claim sweep compared every rule the header states for every input with
the engine's code. Five rules differed in forms the engine refuses to load,
and the reader now refuses each: a variable with more than one computation
mode, in any class a read module defines; a defined_for that names an Enum
or str variable; a variable name in two files; a parameter file that
repeats a key; and a .yml file in the federal SSI parameter tree, which the
table would leave out. The engine also refuses a variable with no label,
which the reader does not check; the header states that limit, and the
core harness gives its invented variables labels. A static oracle checks
the core constants the reader mirrors: the parameter suffixes, the skipped
names, the dated-key pattern and the numeric value types.

Checks: contract 20, runner unit 41 and inventory 723 passed, through
safe-pytest at two workers. The four new engine tests that build no
country system passed: the three core-harness tests and the static
constants test. Regeneration with -I gives the same inventory.json bytes
(sha256 93f6efbf...), and the full records of 2.2.1 and 2.18.0 under this
reader equal those under f92719c's. Collection gives unit 784 and
oracle_policyengine 27 over the five SSI modules, plus the moved test.
black -l 79, ruff and git diff --check are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
O3 and P14 were real test gaps: the reader refuses each layout and the
mutant admits it. B9 is equivalent on both pinned releases, but the reader
still refuses a boundary's literal adds that name itself or an absent
parameter, and these tests pin that. Z1 only changed the exception type, so
its test pins the reader's own ValueError, for a list and for an empty file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits November 1, 2026 12:42
Text only: the abstract syntax trees of both files, docstrings aside, match
208b4d4's. The reader's docstrings now say that a bare expected string
refuses while a mapping marked expected joins the union, that index.yml and
reference.yml load as no parameter, that a self-name refuses on any date,
and which other forms the engine refuses to load. A test comment now says
the engine raises on the two cases it heads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both tier files take master's blobs; the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master's counts plus SSI0's modules: unit 19,504 + 790, oracle 308 + 28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits November 1, 2026 14:33
Both tier files take master's blobs; the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master's counts plus SSI0's modules: unit 19,664 + 790, oracle 308 + 28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 15's two medium findings, each a claim that went too far. Neither
changes a record or a runtime path.

The reader's sentence on the .yml refusal named the stems index and
reference, but the pinned core also skips __pycache__ as a file. The
docstring now names all three.

SSI's three income lists start on 1975-01-01 in both releases, and
prepare accepts 1974, so the future-only list limit reaches pinned
sources and not only invented modules. On the pinned route an earlier
year never reaches them: invented cases in every year from 1972 to 2021,
plus 1000 and 1900, end in a counted RULES_ENGINE_GAP from the worker,
and 2022 gives the first result. The new oracle test holds seven of
those years and 2022. The runner's docstring now says such a year
refuses from the worker, not before any calculation.

The test adds one to oracle_policyengine (337), 27,053 in all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis marked this pull request as ready for review November 2, 2026 14:40
@MaxGhenis
MaxGhenis merged commit 89d064b into master Nov 2, 2026
12 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The Microcosm Dynamics coordinator merged this PR at c865dce17a2eeafffd103fd731639c6b36f0d71c with --merge --match-head-commit, as 89d064b5a28f186c2ef96c70fb53471248489a13 (15:31Z, 2026-11-02).

@MaxGhenis
MaxGhenis deleted the ir/ssi0-20261024 branch November 2, 2026 15:41
MaxGhenis added a commit that referenced this pull request Nov 2, 2026
Master brings SSI0 (#573), which touches no Track B file. The tier files
take master's counts plus this branch's new tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 2, 2026
Master brings SSI0 (#573), which touches no Track B file. The tier files
take master's counts plus this branch's new tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
Master's #573 (SSI0) and #574 (D4) each added a block to the
birth-evidence exclusions, their expected tuple and the reachability
test, where D2 adds its own. Keep master's blocks and put D2's after
them in all three places. Both sides add the same empty
tests/income_resources/__init__.py. The merge takes master's tier
files, and the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
Master's #573 (SSI0) and #574 (D4) each added a block to the
birth-evidence exclusions, their expected tuple and the reachability
test, where CE1 adds its own. Keep master's blocks and put CE1's after
them in all three places. D4's block already lists
src/populace_dynamics/income_resources/__init__.py, which both sides add
as the same blob, so CE1's exclusion blocks keep only coverage_rules.py.
The merge takes master's tier files, and the next commit recounts them.

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

This branch was successfully deployed

1 active deployment
Preview — c865dce1 Deployed Nov 1, 2026 by vercel[bot]
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