Repository navigation
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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>
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>
This was referenced Oct 25, 2026
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
The round-7 review (an Opus 5.5 reviewer, at 81a6db6) asked for revision. Its two medium findings had 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. 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. The reader now applies to every variable what it applied to Enum variables: - The variable is a plain class: its name is bound once, its bases are exactly Variable, it has no keywords or decorators, and its body holds only a leading docstring, single assignments to names Variable's constructor reads, and undecorated formulas. value_type, entity, definition_period, default_value, possible_values, adds and subtracts are each bound at most once, by plain assignment. - value_type, entity and definition_period are each a name the module never binds. A default is a literal of the variable's primitive type (an int or float for a float), 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, is read by one set of rules: top-level imports only, either the model API's star import or named imports from modules under policyengine_us.variables or policyengine_core; classes only at top level, with base Variable or Enum; no attribute store; and no reflective builtin, frame attribute or dunder name. Imported variables modules are followed in turn. Enum classes keep their own checks. The header states the static read's reach, and that only the pinned-engine oracle covers the model API and policyengine_core. - L1: the spelling tests now run over every binding form in BINDING_FORMS, for float, Person and YEAR. A second VALUE_TYPES binding by plain assignment, annotation, `|=`, match capture, import alias or parameter refuses, and Python's float default is shown for each. - L2: 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 also compares by type, so a bool default of 0 refuses. The static-offset differential moved from test_ssi_engine.py to the new test_ssi_static_offset.py, so the engine checks import nothing from the estimates package. Its policy is ssi_invented's INVENTED_POLICY, its Social Security amounts and cut share are invented, and the expected offsets are the pinned engine's own results. It imports the estimates module inside the test, after the interpreter skip, so collecting it without the SSI0 interpreter loads nothing from the estimates package. Corrections to b1d0d02's text: - N1: the S3 reason should also name an entity's or period's name among the bindings refused either way. - N2: the model-API alias test is refused by the older known-name clause, not by the new spelling rule; the PR body credited the new rule. - N3: under mutant D2 the text parse of the core defaults finds no plain table and refuses ("not one plain table"); it does not read the wrong defaults. New tests: every route the review traced, end to end against a control package; 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 the variable module, in a module it imports and in the package init that import runs; string literals that spell reflective or dunder names, admitted in all three places; and an oracle test that loads each route in the pinned engine and shows it changes what the engine gives. Results: - 140 of the 380 inventory tests fail against 81a6db6'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. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SSI0 test modules add 454 tests to master's 25,119: - unit: 441 (contract 20, inventory 380, runner 41) - oracle_policyengine: 13 (engine 9, dataset engine 3, static offset 1) tier_counts.json and the README-tiers table now read unit 18,990, oracle_policyengine 321 and 25,573 in all; the other tiers are master's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Medium 1 needed the reader to refuse code that runs as a module is imported. module_imports now walks import_time_nodes (the module level, class bodies, and each function's and lambda's decorators, arguments, annotations and type parameters, but not their bodies) and refuses any call, decorator, item store or delete, or augmented assignment there, in every variable module, followed module and package init it reads. It also refuses augmented assignment, since binding VALUE_TYPES[float] to a name and applying |= to it changes the table with no call and no item store. UNFOLLOWED_IMPORTS is now an allowlist of names per module, and holds only Simulation from policyengine_core.simulations. The tests add the reviewer's item store, method call and bool default repros, each reaching the table through policyengine_core and through the model API's warnings.sys, an augmented-assignment repro, 15 import-time forms and 8 import forms that refuse, and 5 forms that stay admitted (calls, stores and decorators inside function and lambda bodies, and an aliased Simulation import). An oracle test shows that each change gives the pinned engine's variable another default, and that the unchanged table loads as the reader records it. Medium 2 needed followed imports resolved as the import system resolves them. import_sources finds each step with PathFinder.find_spec, which runs no code. A namespace folder passes; every other step must be a .py origin that SourceFileLoader loads, and the reader parses that origin. A step past a module, a name that a submodule of the imported package could supply, and any other step refuse. The rule as written (every spec a .py origin) would refuse both pinned releases, whose followed paths run through namespace folders, so the reader admits namespace steps, which run no code. parse_variables clears the finder caches before it reads. The tests add the package-shadows-module repro (the frame walk, and a __name__ read) and the sourceless __init__.pyc repro, and cover an extension module beside the source, a submodule name, a step past a module, a case mismatch, UTF-7 decoding of a followed module and of an init, and a finder cache that a kept folder time would leave stale; each checks the loader and file against a fresh interpreter's find_spec where that applies. Medium 3 needed the engine walk's file rules. variable_files mirrors add_variables_from_directory: its globs skip dot names, and a folder's __init__.py is metadata. The stem index, the SSI roots and the state supplement paths all come from it, and a dependency whose stem names more than one file refuses. The tests add the hidden same-stem and SSI __init__.py repros, a hidden SSI root file, a repeated stem read before and after the variable that depends on it, a repeated stem no dependency names (as puf.py is in the pinned release), and a hidden state supplement file. An oracle test checks variable_files against the pinned engine's own walk. Medium 4 needed exact int defaults for float variables. variable_attributes refuses an int default of a float variable unless float(value) == value, and exact_float returns False on OverflowError. The DEFAULT_TYPES comment now says what the engine does with int and bool defaults. test_primitive_default_is_a_literal_of_its_type adds 2**53, 2**53 + 1, -(2**53) - 1 and two overflowing ints, and a Hypothesis test checks the rule against float() near 2**53 and past the float range. The pinned bytes do not move: age's 40 converts exactly. Medium 5 needed the walk's limit stated. The module header now says: 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. Low 1 needed witnesses for the reviewer's surviving mutants: plain_core_import for N1; the UTF-7 followed module for N2; core_module_prefix, core_prefix_import and core_package_import for N6, which this round ports to the allowlist as a prefix match and as a dotless prefix; and adds, subtracts or possible_values bound twice for N8. Each of those mutants now fails a test. Low 2: I chose to compare types. The attribute oracle records the type of each default the engine holds and compares it with the type the engine gives the record: float for an explicit default of a float variable, which the engine converts; member for an enum default; and the record's own type otherwise. It also asserts that the release has an int default the engine converts (age). The notes: the variable_attributes docstring now says the primitive types are builtins that the star import does not rebind, and test_ssi_static_offset.py now says "Every literal". Two claims in earlier text need correcting: the round-8 commit's "Python's float default is shown for each" does not cover the import-alias case, which it did not execute; and the PR's "For every invented module the reader admits" holds over the Hypothesis domain. mutants_r9.py counts a timeout apart from a caught mutant. The augmented_default attribute route now expects the import-time refusal, which comes first. Checks: - The regenerated inventory is byte-identical to the committed one (sha256 93f6efbf...). - test_ssi_contract 20, test_ssi_runner_unit 41, test_ssi_inventory 486, test_ssi_engine 11 and test_ssi_dataset_engine 3 passed. - test_birth_evidence_artifact: 12 passed and 1 failed, the expected test_post_review_exclusions_are_unreachable_from_birth_evidence. - Round 8's 103 mutants, six ported: 95 caught, 8 survived (S3, M11, M17, C4, C5, PV2, PV3 and PV4, each equivalent), none timed out. - Round 9's 41 mutants: 37 caught, 4 survived (I7, I10, F3 and F4, each equivalent), none timed out. - The new inventory tests against 765c487's reader: 93 of 486 fail in each of Hypothesis seeds 0, 1 and 2, with the same IDs. - black -l 79, ruff check and git diff --check pass on the changed files. - Tiers over the five modules: unit 547, oracle_policyengine 14, and none in artifact, integration_psid or reproduction_legacy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The round-9 build found a gap the reader cannot see: Python can run a module's cached bytecode instead of its source. In CPython 3.13.9, SourceFileLoader.get_code (importlib/_bootstrap_external.py) loads __pycache__/<name>.<tag>.pyc when a timestamp file records the source's modification time and size (_validate_timestamp_pyc), and never compares an unchecked hash-based file with its source unless --check-hash-based-pycs is "always". The build showed it with invented modules under the pinned interpreter: an unchecked hash-based pyc ran value 2 where the source says 1, and a checked one ran 1. The reader reads only source, and refusing any module with a cached file would refuse the installed releases. So the header now states the limit beside the directory-walk limit: only the pinned-engine oracle covers cached bytecode. Checks: the regenerated inventory is byte-identical to the committed one; black -l 79 --check and ruff check are clean. No test reads the header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master brings OP1 (#566) and its report fix (#589). Git auto-merged scripts/first_estimates_birth_evidence.py and tests/estimates/test_birth_evidence_artifact.py, which both branches changed: the merge keeps master's OP1 lines and SSI0's exclusions and reachability block, and removes no line from either side. tests/tier_counts.json and tests/README-tiers.md conflicted. They now read master's counts plus the SSI0 test modules' 562 tests, counted by collection at this merge: - unit: 547 (contract 20, runner 41, inventory 486) - oracle_policyengine: 15 (engine 11, dataset engine 3, and the static offset test, one unparametrized function, counted from its source) So they read unit 19,327, oracle_policyengine 323 and 25,912 in all; the other tiers are master's. SSI0 adds no test to the birth-evidence module. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP. 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 eighth, of765c4879, asked for revision;a2b3952banswers it,60b8ca24states one more limit in the reader's header, and2864d622merges master at0f69bbb2and recounts the tiers. The round-9 review is next.What it adds
An annual federal SSI interface to the PolicyEngine release that the latest
policyengine(6.10.2) certifies:policyengine-us2.2.1 andpolicyengine-core3.33.3. It ships with a complete source-to-input contract, published before any SSI computation.src/populace_dynamics/income_resources/ssi/):policyengineinterfaces. It never importspolicyengine_usinternals.pin.jsonrecords the three primary versions, wheel hashes and RECORD hashes;environment_wheels.jsonrecords all 89 installed distributions;docs/analysis/ssi0/requirements-macos-arm64-py313.txtis the hash-locked environment;2dee2fc4fixes this and adds two properties.inventory.json): 52 federal SSI variables, an 86-variable closure, 41 inputs and 24 parameters. It was regenerated byte for byte byscripts/income_resources/inventory_ssi.pyand compared with PE-US 2.18.0. Both releases have the same active chain, inputs and parameters.input_contract.json, versionssi0-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.pyreproduces it together with the review table indocs/analysis/ssi0/input_decisions.md.docs/analysis/ssi0/captured_sources.md). Each capture folder has a.gitattributeswith* -text.Refusals (
RULES_ENGINE_GAP)Invariants
scripts/income_resources/inventory_ssi.py):__init__.pyis metadata. A dependency whose stem names more than one file refuses. Every dependency reaches another inventoried variable or an explicit input.policyengine_us.variables., andSimulationfrompolicyengine_core.simulations. This covers variable modules, followed modules, and the package inits their imports run.PathFinder.find_spec. Namespace folders pass. Every other step must be.pysource loaded bySourceFileLoader, read from that origin; anything else refuses.value_type, entity and period is one plain assignment, of a name its module never binds.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.value_type, default (its value and type), entity, period and enum members against what the engine loads.policyengine_us/variablesoutside 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. Python's source loader can also run a module's cached bytecode in__pycache__instead of its source: a timestamp file that records the source's modification time and size, or an unchecked hash-based file, is never compared with the source. The reader reads only source, so only the pinned-engine oracle covers cached bytecode too.Tests
POPULACE_DYNAMICS_PE_US_PYTHON_SSI0names the pinned interpreter (fallback~/.venvs/policyengine-py-6.10.2/bin/python), and the name contains the classifier's oracle substring;2864d622;tests/income_resources/test_ssi_static_offset.py(1 test) holds the static-offset differential, moved out oftest_ssi_engine.pyso that the engine checks import nothing from the estimates package. It importsestimates/adjusted_poverty.pyinside the test body. CI collects it and skips it, because CI has no SSI0 interpreter. It ran once on the pinned interpreter at765c4879and once at2864d622, each time in a throwaway clone with output kept off-screen: 1 passed. It does not run in CI.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 followstest_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 inadjusted_poverty.pyare the integers 0, 1 and 2 and thefukey passed to_ssi_response.a2b3952b:765c4879's reader, the same 93 in each of three Hypothesis seeds.2864d622adds SSI0's modules to master's counts at0f69bbb2: unit +547 (19,327), oracle_policyengine +15 (323), 25,912 in all. The static-offset test is counted from its source, as one unparametrized function.Since the build
2dee2fc4makes the installation RECORD digest skip entries outside site-packages.14febfdbmergesorigin/masteratfe5ab5abcleanly.d037e91arenames the pinned copy of policyengine-us 2.2.1'sssi_if_takes_up.pyto.py.txt, because black and ruff read every.pyfile 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.bde9d3ddkeeps the birth-evidence seal. The twelve new files undersrc/populace_dynamics/income_resources/are listed inPOST_REVIEW_SOURCE_EXCLUSIONSand 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.pyis 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.48a71983fixes it:immigration_statuscarries them, so an invalid name refuses its own case asINPUT_CONTRACT_GAPbefore dispatch;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.fdd85c6eadds two Hypothesis properties totests/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.b8d9a68acloses 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:__init__hook can drop members;ifblock, a walrus, a match capture, aglobaldeclaration in a function or class, a guarded or aliased import, a star import after the class, or a second binding ofpossible_valuesin 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.encodeaccepts only canonical names;Enumwas matched by spelling; and one refusal test passed only because of the default check.08fdaaf1fixes these, and a further gap found while writing the fix: module code could reach the variable itself, by an attribute store such asinvented_status.possible_values = Other, a decorator, or a rebinding of the variable's name.value_type,possible_valuesanddefault_valueonce each, by plain assignment.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 forNameandAttributenodes; see below.possible_values, the default, a member orencode.Tests at
08fdaaf1:(lambda: None).__globals__[...]and a generator frame'sf_globals;binding_sitesagainst CPython's symbol table for each construct the language reference lists as binding a name;Results at
08fdaaf1: 85 of the 126 inventory tests fail against the parent reader (round 5 found this holds only with the parent'senum_memberscall adapted; with onlybinding_sitesshimmed, 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:matchclass pattern's keyword, such ascase object(__globals__=...), reached a function's globals, because the scan read onlyNameids and attribute names;Variablewas matched by spelling, so a localVariablewith 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 localVariableclass itself and fails loudly. Refusing the form is still right.);Its low findings: a store through a member changed encoding indices unchecked; a
value_typethat was not a plain= Enumskipped 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.b682dcd2fixes these:EnumnorVariable, and every attribute store refuses;Variable's constructor readsvalue_type,possible_valuesanddefault_valuethroughself.set, which a body method or an assignment namedsetcould 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;value_typemust be one plain assignment of a primitive type orEnum, or the inventory refuses (round 6 found this did not hold for a module that rebinds a primitive name;b1d0d029closes it);b1d0d029states 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:08fdaaf1's reader, with no shim;The round-6 delta review (an Opus 5.5 reviewer, at
b682dcd2) asked for revision, with one medium finding:value_typewas read by the spelling of a primitive name, so a module that bindsfloat = Enumgave 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
setbinding 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.b1d0d029fixes these: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);setbinding, a delete through a member and underscore keyword and parameter names; the engine oracle loads the chainedsetpair beside an admitted override;VALUE_TYPEStwice refuses;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_apihas no__all__. BindingEnum,Variable, the enum's name, avalue_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:b682dcd2's reader;81a6db61mergesorigin/masterat1ec57a5d(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 itsvalue_typewas spelledEnum.value_typeis spelled as a primitive could still be an Enum input in the engine, through asetoverride,setattr,globals()or__builtins__;entitieslist or aglobals()store changed what the engine loads.Its low findings: the spelling and
VALUE_TYPEStests exercised one binding form each; and the attribute oracle compared entities through a name conversion that is wrong forSPMUnit, and defaults (likevalidate_core_defaults) by==alone, so1passed forTrue. 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.04e12f58fixes these:Variable, no keywords or decorators, and a body of a leading docstring, single assignments to namesVariable'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;policyengine_us/variablesthat it imports, with the package__init__files the import runs, may import only the model API's star import and named imports from modules underpolicyengine_us.variablesorpolicyengine_core, at top level; may define classes only at top level, onVariableorEnum; may store no attribute; and may name no reflective builtin, frame attribute or dunder name. Imported variables modules are followed in turn;float,PersonandYEAR, and a secondVALUE_TYPESbinding by assignment, annotation,|=, match capture, import alias or parameter refuses, each against Python's answer;policyengine_us.model_api, and compares defaults by type as well as value;validate_core_defaultscompares by type too (round 8 found the oracle compared defaults by==and bool-ness only;a2b3952bmakes it compare types);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:81a6db61's reader, in each of three Hypothesis seeds;0f756216mergesorigin/masteratd8302233(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.765c4879recounts 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:policyengine_coreimport and an item store or method call on itsVALUE_TYPEStable;__init__has only bytecode;__init__.pyfiles, which the engine's directory walk skips, and kept the last of two files with the same stem;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.a2b3952bfixes these:|=changes the table with no call or store); the core imports are an allowlist,Simulationonly;PathFinder.find_spec, and anything but.pysource loaded bySourceFileLoaderrefuses. Namespace steps are admitted, since they run no code and both pinned releases' followed paths use them;OverflowErrorincluded;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, each checked against a fresh interpreter's
find_spec; 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
60b8ca24states this limit in the reader's header, in the sentence in the Invariants section. The regenerated inventory is byte-identical.2864d622mergesorigin/masterat0f69bbb2(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.jsonandtests/README-tiers.mdconflicted 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.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
mainand 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